You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by eg...@apache.org on 2009/03/20 15:14:27 UTC
svn commit: r756476 [1/2] - in /cxf/dosgi/trunk:
discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/
discovery/local/src/main/java/org/osgi/service/discovery/
dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/
dsw/cxf-dsw/src/mai...
Author: eglynn
Date: Fri Mar 20 14:14:26 2009
New Revision: 756476
URL: http://svn.apache.org/viewvc?rev=756476&view=rev
Log:
[dOSGi] Updated to latest Discovery APIs & semantics
Modified:
cxf/dosgi/trunk/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/LocalDiscoveryService.java
cxf/dosgi/trunk/discovery/local/src/main/java/org/osgi/service/discovery/DiscoveredServiceNotification.java
cxf/dosgi/trunk/discovery/local/src/main/java/org/osgi/service/discovery/DiscoveredServiceTracker.java
cxf/dosgi/trunk/discovery/local/src/main/java/org/osgi/service/discovery/ServicePublication.java
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/AbstractClientHook.java
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/CxfListenerHook.java
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/ServiceHookUtils.java
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/DiscoveredServiceNotification.java
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/DiscoveredServiceTracker.java
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/ServicePublication.java
cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/BundleTestContext.java
cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/CxfListenerHookTest.java
cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/CxfPublishHookTest.java
Modified: cxf/dosgi/trunk/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/LocalDiscoveryService.java
URL: http://svn.apache.org/viewvc/cxf/dosgi/trunk/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/LocalDiscoveryService.java?rev=756476&r1=756475&r2=756476&view=diff
==============================================================================
--- cxf/dosgi/trunk/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/LocalDiscoveryService.java (original)
+++ cxf/dosgi/trunk/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/LocalDiscoveryService.java Fri Mar 20 14:14:26 2009
@@ -23,9 +23,11 @@
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;
+import static org.osgi.service.discovery.ServicePublication.PROP_KEY_SERVICE_INTERFACE_NAME;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Hashtable;
@@ -317,13 +319,23 @@
}
private void triggerCallbacks(DiscoveredServiceTracker tracker,
- String match, boolean isFilter,
+ String toMatch,
+ boolean isFilter,
ServiceEndpointDescription sd,
- int notificationType) {
- LOG.info("check if string: " + match + (isFilter ? " matches " : " contained by ") + sd.getProvidedInterfaces());
- if ((isFilter && filterMatches(match, sd))
- || sd.getProvidedInterfaces().contains(match)) {
- tracker.serviceChanged(new TrackerNotification(sd, notificationType));
+ int type) {
+ LOG.info("check if string: " + toMatch + (isFilter ? " matches " : " contained by ") + sd.getProvidedInterfaces());
+
+ TrackerNotification notification =
+ isFilter
+ ? (filterMatches(toMatch, sd)
+ ? new TrackerNotification(sd, true, toMatch, type)
+ : null)
+ : (sd.getProvidedInterfaces().contains(toMatch)
+ ? new TrackerNotification(sd, false, toMatch, type)
+ : null);
+
+ if (notification != null) {
+ tracker.serviceChanged(notification);
}
}
@@ -339,10 +351,25 @@
implements DiscoveredServiceNotification {
private ServiceEndpointDescription sd;
+ private Collection interfaces;
+ private Collection filters;
private int type;
- TrackerNotification(ServiceEndpointDescription sd, int type) {
+ TrackerNotification(ServiceEndpointDescription sd,
+ boolean isFilter,
+ String match,
+ int type) {
this.sd = sd;
+ if (isFilter) {
+ filters = new ArrayList();
+ filters.add(match);
+ interfaces = Collections.EMPTY_SET;
+ } else {
+ interfaces = new ArrayList();
+ interfaces.add(match);
+ filters = Collections.EMPTY_SET;
+ }
+
this.type = type;
}
@@ -353,6 +380,14 @@
public int getType() {
return type;
}
+
+ public Collection getInterfaces() {
+ return interfaces;
+ }
+
+ public Collection getFilters() {
+ return filters;
+ }
}
public void shutdown() {
@@ -391,7 +426,7 @@
String[] interfaceNames = getProvidedInterfaces(sd, interfaceName);
if (interfaceNames != null) {
- d.put(Constants.OBJECTCLASS, interfaceNames);
+ d.put(PROP_KEY_SERVICE_INTERFACE_NAME, interfaceNames);
}
return d;
}
Modified: cxf/dosgi/trunk/discovery/local/src/main/java/org/osgi/service/discovery/DiscoveredServiceNotification.java
URL: http://svn.apache.org/viewvc/cxf/dosgi/trunk/discovery/local/src/main/java/org/osgi/service/discovery/DiscoveredServiceNotification.java?rev=756476&r1=756475&r2=756476&view=diff
==============================================================================
--- cxf/dosgi/trunk/discovery/local/src/main/java/org/osgi/service/discovery/DiscoveredServiceNotification.java (original)
+++ cxf/dosgi/trunk/discovery/local/src/main/java/org/osgi/service/discovery/DiscoveredServiceNotification.java Fri Mar 20 14:14:26 2009
@@ -1,78 +1,102 @@
-/*
- * 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();
-}
+/*
+ * 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;
+
+import java.util.Collection;
+
+/**
+ * Interface for notification on discovered services.
+ *
+ * @version $Revision: 6510 $
+ */
+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();
+
+ /**
+ * Returns interface name criteria of the {@link DiscoveredServiceTracker}
+ * object matching with the interfaces of the ServiceEndpointDescription and
+ * thus caused the notification.
+ *
+ * @return matching interface name criteria of the
+ * {@link DiscoveredServiceTracker} object being notified.
+ */
+ Collection/* <String> */getInterfaces();
+
+ /**
+ * Returns filters of the {@link DiscoveredServiceTracker} object matching
+ * with the ServiceEndpointDescription and thus caused the notification.
+ *
+ * @return matching filters of the {@link DiscoveredServiceTracker} object
+ * being notified.
+ */
+ Collection/* <String> */getFilters();
+}
+
Modified: cxf/dosgi/trunk/discovery/local/src/main/java/org/osgi/service/discovery/DiscoveredServiceTracker.java
URL: http://svn.apache.org/viewvc/cxf/dosgi/trunk/discovery/local/src/main/java/org/osgi/service/discovery/DiscoveredServiceTracker.java?rev=756476&r1=756475&r2=756476&view=diff
==============================================================================
--- cxf/dosgi/trunk/discovery/local/src/main/java/org/osgi/service/discovery/DiscoveredServiceTracker.java (original)
+++ cxf/dosgi/trunk/discovery/local/src/main/java/org/osgi/service/discovery/DiscoveredServiceTracker.java Fri Mar 20 14:14:26 2009
@@ -1,62 +1,72 @@
-/*
- * 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);
-}
+/*
+ * 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: 6553 $
+ */
+public interface DiscoveredServiceTracker {
+
+ /**
+ * Optional ServiceRegistration property which contains 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";
+
+ /**
+ * Optional ServiceRegistration property which contains filters for services
+ * this tracker is interested in. <br>
+ * Note that these filters need to take into account service publication
+ * properties which are not necessarily the same as properties under which a
+ * service is registered. See {@link ServicePublication} for some standard
+ * properties used to publish service metadata. <br>
+ * The following sample filter will make Discovery notify the
+ * DiscoveredServiceTracker about services providing interface
+ * 'my.company.foo' of version '1.0.1.3':<br>
+ * "(&(service.interface=my.company.foo)(service.interface.version=my.company.foo|1.0.1.3))". <br>
+ * Value of this property is of type Collection (<? extends String%gt;).
+ * 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. <br>
+ * If multiple criteria match, then the tracker is notified about each of
+ * them. This can be done either by a single notification callback or by
+ * multiple subsequent ones.
+ *
+ * @param notification the <code>DiscoveredServiceNotification</code> object
+ * describing the change.
+ */
+ void serviceChanged(DiscoveredServiceNotification notification);
+}
Modified: cxf/dosgi/trunk/discovery/local/src/main/java/org/osgi/service/discovery/ServicePublication.java
URL: http://svn.apache.org/viewvc/cxf/dosgi/trunk/discovery/local/src/main/java/org/osgi/service/discovery/ServicePublication.java?rev=756476&r1=756475&r2=756476&view=diff
==============================================================================
--- cxf/dosgi/trunk/discovery/local/src/main/java/org/osgi/service/discovery/ServicePublication.java (original)
+++ cxf/dosgi/trunk/discovery/local/src/main/java/org/osgi/service/discovery/ServicePublication.java Fri Mar 20 14:14:26 2009
@@ -1,109 +1,116 @@
-/*
- * 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 = ":";
-}
+/*
+ * 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. Note also that a Discovery implementation may require provision
+ * of additional properties, e.g. some of the standard properties defined below,
+ * or may make special use of them in case they are provided. For example an
+ * SLP-based Discovery might use the value provided with the
+ * {@link #PROP_KEY_ENDPOINT_LOCATION} property for construction of a SLP-URL
+ * used to publish the service.<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, and the actual publication via Discovery
+ * mechanisms has to succeed.
+ *
+ * @version $Revision: 6485 $
+ */
+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). <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 constant for association of interface-specific values with the
+ * particular interface name. See also
+ * {@link #PROP_KEY_SERVICE_INTERFACE_VERSION} and
+ * {@link #PROP_KEY_ENDPOINT_INTERFACE_NAME} properties which describe such
+ * interface-specific values.
+ */
+ public static final String SEPARATOR = "|";
+}
Modified: cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/AbstractClientHook.java
URL: http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/AbstractClientHook.java?rev=756476&r1=756475&r2=756476&view=diff
==============================================================================
--- cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/AbstractClientHook.java (original)
+++ cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/AbstractClientHook.java Fri Mar 20 14:14:26 2009
@@ -24,10 +24,13 @@
import static org.osgi.service.discovery.DiscoveredServiceTracker.PROP_KEY_MATCH_CRITERIA_FILTERS;
import static org.osgi.service.discovery.DiscoveredServiceTracker.PROP_KEY_MATCH_CRITERIA_INTERFACES;
import static org.osgi.service.discovery.ServicePublication.PROP_KEY_ENDPOINT_ID;
+import static org.osgi.service.discovery.ServicePublication.PROP_KEY_SERVICE_INTERFACE_NAME;
+
import java.util.ArrayList;
import java.util.Collection;
import java.util.Dictionary;
+import java.util.Iterator;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
@@ -38,6 +41,8 @@
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.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.discovery.DiscoveredServiceNotification;
@@ -52,8 +57,8 @@
private DiscoveredServiceTracker tracker;
private Dictionary trackerProperties = new Hashtable();
private ServiceRegistration trackerRegistration;
- private Map<String, ServiceEndpointDescription> discoveredServices =
- new HashMap<String, ServiceEndpointDescription>();
+ private Map<String, ServiceRegistration> discoveredServices =
+ new HashMap<String, ServiceRegistration>();
protected AbstractClientHook(BundleContext bc, CxfDistributionProvider dp) {
super(bc, dp);
@@ -63,28 +68,40 @@
tracker,
trackerProperties);
}
-
- protected void processClientDescriptions(BundleContext requestingContext,
- String interfaceName,
- String filter) {
- lookupDiscoveryService(interfaceName, filter);
- }
-
- protected void processServiceDescription(ServiceEndpointDescription sd,
- BundleContext requestingContext,
- String interfaceName) {
+ protected void processNotification(DiscoveredServiceNotification notification,
+ BundleContext requestingContext) {
+ ServiceEndpointDescription sd =
+ notification.getServiceEndpointDescription();
if (sd.getProperty(Constants.REMOTE_INTERFACES_PROPERTY) == null) {
+ LOG.info("not proxifying service, enabling property unset: "
+ + Constants.REMOTE_INTERFACES_PROPERTY);
return;
}
ConfigurationTypeHandler handler =
ServiceHookUtils.getHandler(getContext(), sd, getDistributionProvider(), getHandlerProperties());
if (handler == null) {
+ LOG.info("not proxifying service, config type handler null");
return;
}
-
+
+ Collection<String> matchingInterfaces =
+ getMatchingInterfaces(notification, requestingContext);
+
+ for (String interfaceName : matchingInterfaces) {
+ proxifyMatchingInterface(interfaceName, sd, handler, requestingContext);
+ }
+
+ }
+
+
+ private void proxifyMatchingInterface(String interfaceName,
+ ServiceEndpointDescription sd,
+ ConfigurationTypeHandler handler,
+ BundleContext requestingContext) {
+
try {
Class<?> iClass = getContext().getBundle().loadClass(interfaceName);
if (iClass != null) {
@@ -99,19 +116,73 @@
actualContext = requestingContext;
}
- synchronized(this) {
- if (cacheEndpointId(sd)) {
- actualContext.registerService(new String[]{interfaceName},
- new ClientServiceFactory(actualContext, iClass, sd, handler),
- new Hashtable<String, Object>(getProperties(sd)));
+ synchronized(discoveredServices) {
+ if (unknownEndpointId(sd)) {
+ ServiceRegistration proxyRegistration =
+ actualContext.registerService(interfaceName,
+ new ClientServiceFactory(actualContext, iClass, sd, handler),
+ new Hashtable<String, Object>(getProperties(sd)));
+ cacheEndpointId(sd, proxyRegistration);
}
}
+ } else {
+ LOG.info("not proxifying service, cannot load interface class: "
+ + interfaceName);
}
} catch (ClassNotFoundException ex) {
LOG.warning("No class can be found for " + interfaceName);
}
}
+
+ private Collection<String> getMatchingInterfaces(DiscoveredServiceNotification notification, BundleContext context) {
+
+ Collection<String> matches = new ArrayList<String>();
+ Iterator interfaces = notification.getServiceEndpointDescription().getProvidedInterfaces().iterator();
+
+ while (interfaces.hasNext()) {
+ String currInterface = (String)interfaces.next();
+ boolean matched = false;
+ Iterator matchedInterfaces =
+ notification.getInterfaces().iterator();
+ while (matchedInterfaces.hasNext() && !matched) {
+ matched = currInterface.equals(matchedInterfaces.next());
+ if (matched) {
+ matches.add(currInterface);
+ }
+ }
+ Iterator matchedFilters =
+ notification.getFilters().iterator();
+ while (matchedFilters.hasNext() && !matched) {
+ String filterString = (String)matchedFilters.next();
+ try {
+ Filter filter = context.createFilter(filterString);
+ matched =
+ filter.match(getProperties(notification, currInterface));
+ } catch (InvalidSyntaxException ise) {
+ LOG.warning("invalid filter syntax: " + filterString);
+ }
+ if (matched) {
+ matches.add(currInterface);
+ }
+ }
+ }
+
+ return matches;
+ }
+ private Hashtable getProperties(DiscoveredServiceNotification notification,
+ String interfaceName) {
+ Hashtable ret = new Hashtable();
+ Map properties = notification.getServiceEndpointDescription().getProperties();
+ Iterator keys = notification.getServiceEndpointDescription().getPropertyKeys().iterator();
+ while (keys.hasNext()) {
+ String key = (String)keys.next();
+ ret.put(key, properties.get(key));
+ }
+ ret.put(PROP_KEY_SERVICE_INTERFACE_NAME, interfaceName);
+ return ret;
+ }
+
@SuppressWarnings("unchecked")
protected Map<String, Object> getProperties(ServiceEndpointDescription sd) {
Map<String, Object> props = new HashMap<String, Object>();
@@ -122,6 +193,8 @@
}
protected synchronized void lookupDiscoveryService(String interfaceName, String filterValue) {
+ LOG.info("lookup discovery service: interface: " + interfaceName
+ + " filter: " + filterValue);
if (interfaceName != null) {
append(trackerProperties,
@@ -148,12 +221,14 @@
existing.add(additional);
}
- private synchronized boolean cacheEndpointId(ServiceEndpointDescription notified) {
+ /**
+ * @pre called with discoveredServices mutex held
+ */
+ private boolean unknownEndpointId(ServiceEndpointDescription notified) {
String endpointId = (String)notified.getProperty(PROP_KEY_ENDPOINT_ID);
if (endpointId != null) {
boolean duplicate = discoveredServices.containsKey(endpointId);
if (!duplicate) {
- discoveredServices.put(endpointId, notified);
LOG.info("registering proxy for endpoint ID: " + endpointId);
} else {
LOG.warning("ignoring duplicate notification for endpoint ID: "
@@ -166,10 +241,31 @@
}
}
- private synchronized void unCacheEndpointId(ServiceEndpointDescription notified) {
+ /**
+ * @pre called with discoveredServices mutex held
+ */
+ private void cacheEndpointId(ServiceEndpointDescription notified, ServiceRegistration registration) {
String endpointId = (String)notified.getProperty(PROP_KEY_ENDPOINT_ID);
if (endpointId != null) {
- discoveredServices.remove(endpointId);
+ discoveredServices.put(endpointId, registration);
+ LOG.info("caching proxy registration for endpoint ID: " + endpointId);
+ } else {
+ LOG.warning("cannot cache proxy registration as endpoint ID unset");
+ }
+ }
+
+ private void unCacheEndpointId(ServiceEndpointDescription notified) {
+ String endpointId = (String)notified.getProperty(PROP_KEY_ENDPOINT_ID);
+ ServiceRegistration proxyRegistration = null;
+ if (endpointId != null) {
+ synchronized (discoveredServices) {
+ proxyRegistration = discoveredServices.remove(endpointId);
+ }
+ }
+ if (proxyRegistration != null) {
+ LOG.info("unregistering proxy service for endpoint ID: "
+ + endpointId);
+ proxyRegistration.unregister();
}
}
@@ -184,14 +280,7 @@
+ notified.getProvidedInterfaces()
+ " endpoint id: "
+ notification.getServiceEndpointDescription().getProperty(PROP_KEY_ENDPOINT_ID));
- // 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);
+ processNotification(notification, getContext());
break;
case UNAVAILABLE:
@@ -200,8 +289,6 @@
+ " endpoint id: "
+ notification.getServiceEndpointDescription().getProperty(PROP_KEY_ENDPOINT_ID));
unCacheEndpointId(notified);
- // we don't currently use this notification, but we could do
- // so to allow to drive transparent fail-over
break;
case MODIFIED:
Modified: cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/CxfListenerHook.java
URL: http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/CxfListenerHook.java?rev=756476&r1=756475&r2=756476&view=diff
==============================================================================
--- cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/CxfListenerHook.java (original)
+++ cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/CxfListenerHook.java Fri Mar 20 14:14:26 2009
@@ -31,6 +31,8 @@
import org.osgi.framework.Constants;
import org.osgi.framework.hooks.service.ListenerHook;
+import static org.osgi.service.discovery.ServicePublication.PROP_KEY_SERVICE_INTERFACE_NAME;
+
public class CxfListenerHook extends AbstractClientHook implements ListenerHook {
private static final Logger LOG = Logger.getLogger(CxfListenerHook.class.getName());
@@ -40,6 +42,8 @@
".*\\(" + Constants.OBJECTCLASS + "=([a-zA-Z_0-9.]+)\\).*";
private final static Pattern CLASS_NAME_PATTERN =
Pattern.compile(CLASS_NAME_EXPRESSION);
+ private final static String CLASS_NAME_BASE =
+ "(" + Constants.OBJECTCLASS + "=";
private static final Set<String> SYSTEM_PACKAGES;
static {
@@ -50,6 +54,7 @@
SYSTEM_PACKAGES.add("ch.ethz.iks.slp");
SYSTEM_PACKAGES.add("org.ungoverned.osgi.service");
SYSTEM_PACKAGES.add("org.springframework.osgi.context.event.OsgiBundleApplicationContextListener");
+ SYSTEM_PACKAGES.add("java.net.ContentHandler");
}
public CxfListenerHook(BundleContext bc, CxfDistributionProvider dp) {
@@ -68,44 +73,48 @@
for (Iterator/*<? extends ListenerHook.ListenerInfo>*/ it = listeners.iterator(); it.hasNext(); ) {
ListenerHook.ListenerInfo listener = (ListenerHook.ListenerInfo) it.next();
- if (listener.getFilter() == null
- || listener.getBundleContext() == getContext()) {
- continue;
- }
- String className = getClassNameFromFilter(listener.getFilter());
- if (!isClassSupported(className)) {
- continue;
- }
+ String className = getClassNameFromFilter(listener.getFilter());
+
+ if (!(listener.getFilter() == null
+ || listener.getBundleContext() == getContext()
+ || isClassExcluded(className))) {
- processClientDescriptions(listener.getBundleContext(),
- className,
- listener.getFilter());
+ if (onlyClassNameInFilter(className, listener.getFilter())) {
+ lookupDiscoveryService(className, null);
+ } else {
+ String filter = listener.getFilter().replaceAll("objectClass",
+ PROP_KEY_SERVICE_INTERFACE_NAME);
+ lookupDiscoveryService(null, filter);
+ }
+ }
}
}
private String getClassNameFromFilter(String filter) {
- if (filter == null) {
- return null;
- }
- Matcher matcher = CLASS_NAME_PATTERN.matcher(filter);
- if (matcher.matches() && matcher.groupCount() >= 1) {
- return matcher.group(1);
+ if (filter != null) {
+ Matcher matcher = CLASS_NAME_PATTERN.matcher(filter);
+ if (matcher.matches() && matcher.groupCount() >= 1) {
+ return matcher.group(1);
+ }
}
-
return null;
}
+
+ private boolean onlyClassNameInFilter(String className, String filter) {
+ return (CLASS_NAME_BASE + className + ")").equals(filter);
+ }
- private static boolean isClassSupported(String className) {
+ private static boolean isClassExcluded(String className) {
if (className == null) {
- return false;
+ return true;
}
for (String p : SYSTEM_PACKAGES) {
if (className.startsWith(p)) {
LOG.fine("Lookup for " + className + " is ignored");
- return false;
+ return true;
}
}
- return true;
+ return false;
}
}
Modified: cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/ServiceHookUtils.java
URL: http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/ServiceHookUtils.java?rev=756476&r1=756475&r2=756476&view=diff
==============================================================================
--- cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/ServiceHookUtils.java (original)
+++ cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/ServiceHookUtils.java Fri Mar 20 14:14:26 2009
@@ -154,7 +154,7 @@
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/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/DiscoveredServiceNotification.java
URL: http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/DiscoveredServiceNotification.java?rev=756476&r1=756475&r2=756476&view=diff
==============================================================================
--- cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/DiscoveredServiceNotification.java (original)
+++ cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/DiscoveredServiceNotification.java Fri Mar 20 14:14:26 2009
@@ -1,78 +1,102 @@
-/*
- * 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();
-}
+/*
+ * 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;
+
+import java.util.Collection;
+
+/**
+ * Interface for notification on discovered services.
+ *
+ * @version $Revision: 6510 $
+ */
+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();
+
+ /**
+ * Returns interface name criteria of the {@link DiscoveredServiceTracker}
+ * object matching with the interfaces of the ServiceEndpointDescription and
+ * thus caused the notification.
+ *
+ * @return matching interface name criteria of the
+ * {@link DiscoveredServiceTracker} object being notified.
+ */
+ Collection/* <String> */getInterfaces();
+
+ /**
+ * Returns filters of the {@link DiscoveredServiceTracker} object matching
+ * with the ServiceEndpointDescription and thus caused the notification.
+ *
+ * @return matching filters of the {@link DiscoveredServiceTracker} object
+ * being notified.
+ */
+ Collection/* <String> */getFilters();
+}
+
Modified: cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/DiscoveredServiceTracker.java
URL: http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/DiscoveredServiceTracker.java?rev=756476&r1=756475&r2=756476&view=diff
==============================================================================
--- cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/DiscoveredServiceTracker.java (original)
+++ cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/DiscoveredServiceTracker.java Fri Mar 20 14:14:26 2009
@@ -1,62 +1,72 @@
-/*
- * 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);
-}
+/*
+ * 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: 6553 $
+ */
+public interface DiscoveredServiceTracker {
+
+ /**
+ * Optional ServiceRegistration property which contains 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";
+
+ /**
+ * Optional ServiceRegistration property which contains filters for services
+ * this tracker is interested in. <br>
+ * Note that these filters need to take into account service publication
+ * properties which are not necessarily the same as properties under which a
+ * service is registered. See {@link ServicePublication} for some standard
+ * properties used to publish service metadata. <br>
+ * The following sample filter will make Discovery notify the
+ * DiscoveredServiceTracker about services providing interface
+ * 'my.company.foo' of version '1.0.1.3':<br>
+ * "(&(service.interface=my.company.foo)(service.interface.version=my.company.foo|1.0.1.3))". <br>
+ * Value of this property is of type Collection (<? extends String%gt;).
+ * 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. <br>
+ * If multiple criteria match, then the tracker is notified about each of
+ * them. This can be done either by a single notification callback or by
+ * multiple subsequent ones.
+ *
+ * @param notification the <code>DiscoveredServiceNotification</code> object
+ * describing the change.
+ */
+ void serviceChanged(DiscoveredServiceNotification notification);
+}
Modified: cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/ServicePublication.java
URL: http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/ServicePublication.java?rev=756476&r1=756475&r2=756476&view=diff
==============================================================================
--- cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/ServicePublication.java (original)
+++ cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/ServicePublication.java Fri Mar 20 14:14:26 2009
@@ -1,109 +1,116 @@
-/*
- * 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 = ":";
-}
+/*
+ * 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. Note also that a Discovery implementation may require provision
+ * of additional properties, e.g. some of the standard properties defined below,
+ * or may make special use of them in case they are provided. For example an
+ * SLP-based Discovery might use the value provided with the
+ * {@link #PROP_KEY_ENDPOINT_LOCATION} property for construction of a SLP-URL
+ * used to publish the service.<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, and the actual publication via Discovery
+ * mechanisms has to succeed.
+ *
+ * @version $Revision: 6485 $
+ */
+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). <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 constant for association of interface-specific values with the
+ * particular interface name. See also
+ * {@link #PROP_KEY_SERVICE_INTERFACE_VERSION} and
+ * {@link #PROP_KEY_ENDPOINT_INTERFACE_NAME} properties which describe such
+ * interface-specific values.
+ */
+ public static final String SEPARATOR = "|";
+}
Modified: cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/BundleTestContext.java
URL: http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/BundleTestContext.java?rev=756476&r1=756475&r2=756476&view=diff
==============================================================================
--- cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/BundleTestContext.java (original)
+++ cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/BundleTestContext.java Fri Mar 20 14:14:26 2009
@@ -40,17 +40,21 @@
public class BundleTestContext implements BundleContext {
private Bundle bundle;
- private Object serviceObject;
private Map<String, ServiceReference> testReferences = new
HashMap<String, ServiceReference>();
private Map<String, ServiceRegistration> testRegistrations = new
HashMap<String, ServiceRegistration>();
+ private Map<ServiceReference, Object> registeredServices = new
+ HashMap<ServiceReference, Object>();
+ private List<Object> registeredServiceList = new ArrayList<Object>();
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>>();
+ private Map<String, Filter> filters = new HashMap<String, Filter>();
+
public BundleTestContext(Bundle b) {
bundle = b;
@@ -68,8 +72,8 @@
public void addServiceListener(ServiceListener arg0, String arg1) throws InvalidSyntaxException {
}
- public Filter createFilter(String arg0) throws InvalidSyntaxException {
- return null;
+ public Filter createFilter(String filterString) throws InvalidSyntaxException {
+ return filters.get(filterString);
}
public ServiceReference[] getAllServiceReferences(String arg0, String arg1) throws InvalidSyntaxException {
@@ -97,7 +101,7 @@
}
public Object getService(ServiceReference sref) {
- return serviceObject;
+ return registeredServices.get(sref);
}
public ServiceReference getServiceReference(String name) {
@@ -120,17 +124,28 @@
}
public ServiceRegistration registerService(String[] names, Object service, Dictionary props) {
+
for (String s : names) {
- registeredReferences.put(s, testReferences.get(s));
+ registeredRegistrations.put(s, testRegistrations.get(s));
+ ServiceReference sref = testReferences.get(s);
+ registeredReferences.put(s, sref);
+ registeredServices.put(sref, service);
+ registeredServiceList.add(service);
+ cacheProperties(s, props);
}
- serviceObject = service;
- return null;
+
+ return testRegistrations.get(names[0]);
}
public ServiceRegistration registerService(String clz, Object obj, Dictionary props) {
- registeredRegistrations.put(clz, testRegistrations.get(clz));
+ ServiceRegistration registration = testRegistrations.get(clz);
+ registeredRegistrations.put(clz, registration);
+ ServiceReference sref = testReferences.get(clz);
+ registeredReferences.put(clz, sref);
+ registeredServices.put(sref, obj);
+ registeredServiceList.add(obj);
cacheProperties(clz, props);
- return testRegistrations.get(clz);
+ return registration;
}
public void removeBundleListener(BundleListener arg0) {
@@ -154,6 +169,10 @@
public void addServiceRegistration(String name, ServiceRegistration reg) {
testRegistrations.put(name, reg);
}
+
+ public void addFilter(String s, Filter filter) {
+ filters.put(s, filter);
+ }
public Map<String, ServiceReference> getRegisteredReferences() {
return registeredReferences;
@@ -163,6 +182,10 @@
return registeredRegistrations;
}
+ public List<Object> getRegisteredServices() {
+ return registeredServiceList;
+ }
+
public Map<String, List<Dictionary>> getRegisteredProperties() {
return registeredProperties;
}
Modified: cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/CxfListenerHookTest.java
URL: http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/CxfListenerHookTest.java?rev=756476&r1=756475&r2=756476&view=diff
==============================================================================
--- cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/CxfListenerHookTest.java (original)
+++ cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/CxfListenerHookTest.java Fri Mar 20 14:14:26 2009
@@ -18,14 +18,18 @@
*/
package org.apache.cxf.dosgi.dsw.hooks;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.Dictionary;
import java.util.Hashtable;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.cxf.dosgi.dsw.service.CxfDistributionProvider;
+import org.apache.cxf.dosgi.dsw.service.ServiceEndpointDescriptionImpl;
import org.easymock.classextension.EasyMock;
import org.easymock.classextension.IMocksControl;
import org.junit.Assert;
@@ -33,11 +37,18 @@
import org.junit.Test;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.framework.hooks.service.ListenerHook;
+import org.osgi.service.discovery.DiscoveredServiceNotification;
import org.osgi.service.discovery.DiscoveredServiceTracker;
+import org.osgi.service.discovery.ServiceEndpointDescription;
+
+import static org.osgi.service.discovery.DiscoveredServiceNotification.AVAILABLE;
+import static org.osgi.service.discovery.DiscoveredServiceNotification.UNAVAILABLE;
+import static org.osgi.service.discovery.ServicePublication.PROP_KEY_SERVICE_INTERFACE_NAME;
public class CxfListenerHookTest extends Assert {
@@ -89,38 +100,123 @@
assertEquals(1, registeredRefs.size());
} */
- //@Test
- public void testListenerHook() throws Exception {
+ @Test
+ public void testTrackerPropertiesOnlyClassInFilterWithMatchingInterface() throws Exception {
+ String filter = "(objectClass=" + TestService.class.getName() + ")";
+ doTestTrackerPropertiesSet(filter,
+ "osgi.discovery.interest.interfaces",
+ TestService.class.getName(),
+ asList(TestService.class.getName()),
+ Collections.EMPTY_SET);
+ }
+
+ @Test
+ public void testTrackerPropertiesGenericFilterWithMatchingInterface() throws Exception {
+ String filter = "(&(objectClass=" + TestService.class.getName()
+ + ")(colour=blue))";
+ doTestTrackerPropertiesSet(filter,
+ "osgi.discovery.interest.filters",
+ replacePredicate(filter),
+ asList(TestService.class.getName()),
+ Collections.EMPTY_SET);
+ }
+
+ @Test
+ public void testTrackerPropertiesOnlyClassInFilterWithMatchingFilter() throws Exception {
+ String filter = "(objectClass=" + TestService.class.getName() + ")";
+ doTestTrackerPropertiesSet(filter,
+ "osgi.discovery.interest.interfaces",
+ TestService.class.getName(),
+ Collections.EMPTY_SET,
+ asList(replacePredicate(filter)));
+ }
+
+ @Test
+ public void testTrackerPropertiesGenericFilterWithMatchingFilter() throws Exception {
+ String filter = "(&(objectClass=" + TestService.class.getName()
+ + ")(colour=blue))";
+ doTestTrackerPropertiesSet(filter,
+ "osgi.discovery.interest.filters",
+ replacePredicate(filter),
+ Collections.EMPTY_SET,
+ asList(replacePredicate(filter)));
+ }
+
+ @Test
+ public void testTrackerPropertiesOnlyClassInFilterWithMatchingBoth() throws Exception {
+ String filter = "(objectClass=" + TestService.class.getName() + ")";
+ doTestTrackerPropertiesSet(filter,
+ "osgi.discovery.interest.interfaces",
+ TestService.class.getName(),
+ asList(TestService.class.getName()),
+ asList(replacePredicate(filter)));
+ }
+
+ @Test
+ public void testTrackerPropertiesGenericFilterWithMatchingBoth() throws Exception {
+ String filter = "(&(objectClass=" + TestService.class.getName()
+ + ")(colour=blue))";
+ doTestTrackerPropertiesSet(filter,
+ "osgi.discovery.interest.filters",
+ replacePredicate(filter),
+ Collections.EMPTY_SET,
+ asList(replacePredicate(filter)));
+ }
+
+ private void doTestTrackerPropertiesSet(final String filter,
+ String propKey,
+ String propValue,
+ Collection matchingInterfaces,
+ Collection matchingFilters) throws Exception {
Bundle bundle = control.createMock(Bundle.class);
- bundle.findEntries(EasyMock.eq("OSGI-INF/remote-service"),
- EasyMock.eq("*.xml"), EasyMock.anyBoolean());
- EasyMock.expectLastCall().andReturn(Collections.enumeration(
- Arrays.asList(getClass().getResource("/OSGI-INF/remote-service/remote-services.xml"))));
- Dictionary<String, String> bundleHeaders = new Hashtable<String, String>();
+ Dictionary<String, String> bundleHeaders =
+ new Hashtable<String, String>();
bundleHeaders.put(org.osgi.framework.Constants.BUNDLE_NAME,
"Test Bundle");
bundleHeaders.put(org.osgi.framework.Constants.BUNDLE_VERSION,
"1.0.0");
bundle.getHeaders();
- EasyMock.expectLastCall().andReturn(bundleHeaders).anyTimes();
+ EasyMock.expectLastCall().andReturn(bundleHeaders).times(2);
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();
+ EasyMock.expectLastCall().andReturn(TestService.class).times(2);
+ final BundleContext requestingContext =
+ control.createMock(BundleContext.class);
BundleTestContext dswContext = new BundleTestContext(bundle);
- ServiceReference reference = control.createMock(ServiceReference.class);
- dswContext.addServiceReference(serviceClass, reference);
+ ServiceRegistration serviceRegistration =
+ control.createMock(ServiceRegistration.class);
+ dswContext.addServiceRegistration(serviceClass, serviceRegistration);
+ serviceRegistration.unregister();
+ EasyMock.expectLastCall().times(1);
+ ServiceReference serviceReference =
+ control.createMock(ServiceReference.class);
+ dswContext.addServiceReference(serviceClass, serviceReference);
final String trackerClass = DiscoveredServiceTracker.class.getName();
- ServiceRegistration registration =
+ ServiceRegistration trackerRegistration =
control.createMock(ServiceRegistration.class);
- dswContext.addServiceRegistration(trackerClass, registration);
- registration.setProperties(EasyMock.isA(Dictionary.class));
+ dswContext.addServiceRegistration(trackerClass, trackerRegistration);
+ ServiceReference trackerReference =
+ control.createMock(ServiceReference.class);
+ dswContext.addServiceReference(trackerClass, trackerReference);
+
+ List property = asList(propValue);
+ Dictionary properties = new Hashtable();
+ properties.put(propKey, property);
+ trackerRegistration.setProperties(properties);
EasyMock.expectLastCall();
+ if (matchingInterfaces.size() == 0 && matchingFilters.size() > 0) {
+ Iterator filters = matchingFilters.iterator();
+ while (filters.hasNext()) {
+ Filter f = control.createMock(Filter.class);
+ dswContext.addFilter((String)filters.next(), f);
+ f.match(EasyMock.isA(Dictionary.class));
+ EasyMock.expectLastCall().andReturn(true);
+ }
+ }
+
control.replay();
CxfListenerHook hook = new CxfListenerHook(dswContext, null);
@@ -131,24 +227,45 @@
}
public String getFilter() {
- return "(objectClass=" + serviceClass + ")";
+ return filter;
}
};
hook.added(Collections.singleton(info));
+
+ DiscoveredServiceTracker tracker = (DiscoveredServiceTracker)
+ dswContext.getService(trackerReference);
+ assertNotNull(tracker);
+
+ Collection interfaces = asList(serviceClass);
+
+ notifyAvailable(tracker, matchingInterfaces, matchingFilters, "1234");
+ notifyAvailable(tracker, matchingInterfaces, matchingFilters, "5678");
+ notifyAvailable(tracker, matchingInterfaces, matchingFilters, "1234");
+ notifyUnAvailable(tracker, "1234");
+ notifyUnAvailable(tracker, "5678");
+
+ notifyAvailable(tracker, matchingInterfaces, matchingFilters , "1234");
+
+ control.verify();
+
Map<String, ServiceReference> registeredRefs =
dswContext.getRegisteredReferences();
assertNotNull(registeredRefs);
- assertEquals(1, registeredRefs.size());
+ assertEquals(2, registeredRefs.size());
assertNotNull(registeredRefs.get(serviceClass));
- assertSame(reference, registeredRefs.get(serviceClass));
+ assertSame(serviceReference, registeredRefs.get(serviceClass));
Map<String, ServiceRegistration> registeredRegs =
dswContext.getRegisteredRegistrations();
assertNotNull(registeredRegs);
- assertEquals(1, registeredRegs.size());
+ assertEquals(2, registeredRegs.size());
assertNotNull(registeredRegs.get(trackerClass));
- assertSame(registration, registeredRegs.get(trackerClass));
+ assertSame(trackerRegistration, registeredRegs.get(trackerClass));
+
+ List<Object> registeredServices = dswContext.getRegisteredServices();
+ assertNotNull(registeredServices);
+ assertEquals(2, registeredServices.size());
}
@Test
@@ -162,4 +279,74 @@
assertSame(dp, clh.getDistributionProvider());
}
+ private void notifyAvailable(DiscoveredServiceTracker tracker,
+ Collection interfaces,
+ Collection filters,
+ String endpointId) {
+ Map<String, Object> props = new Hashtable<String, Object>();
+ props.put("osgi.remote.interfaces", "*");
+ props.put("osgi.remote.endpoint.id", endpointId);
+ tracker.serviceChanged(new Notification(AVAILABLE,
+ TestService.class.getName(),
+ interfaces,
+ filters,
+ props));
+ }
+
+ private void notifyUnAvailable(DiscoveredServiceTracker tracker,
+ String endpointId) {
+ Map<String, Object> props = new Hashtable<String, Object>();
+ props.put("osgi.remote.endpoint.id", endpointId);
+ tracker.serviceChanged(new Notification(UNAVAILABLE,
+ TestService.class.getName(),
+ Collections.EMPTY_SET,
+ Collections.EMPTY_SET,
+ props));
+ }
+
+ private List<String> asList(String s) {
+ List l = new ArrayList<String>();
+ l.add(s);
+ return l;
+ }
+
+ private String replacePredicate(String filter) {
+ return filter.replace("objectClass", "service.interface");
+ }
+
+ private class Notification implements DiscoveredServiceNotification {
+ private int type;
+ private ServiceEndpointDescription sed;
+ private Collection interfaces;
+ private Collection filters;
+
+ Notification(int type,
+ String interfaceName,
+ Collection interfaces,
+ Collection filters,
+ Map<String, Object> props) {
+ this.type = type;
+ this.sed =
+ new ServiceEndpointDescriptionImpl(interfaceName, props);
+ this.interfaces = interfaces;
+ this.filters = filters;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public ServiceEndpointDescription getServiceEndpointDescription() {
+ return sed;
+ }
+
+ public Collection getInterfaces() {
+ return interfaces;
+ }
+
+ public Collection getFilters() {
+ return filters;
+ }
+ }
+
}