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/01/28 18:16:21 UTC
svn commit: r738547 [1/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...
Author: eglynn
Date: Wed Jan 28 17:16:16 2009
New Revision: 738547
URL: http://svn.apache.org/viewvc?rev=738547&view=rev
Log:
[dOSGi] add support for interaction with Discovery via white-board pattern
Added:
cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/DiscoveredServiceNotification.java
cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/DiscoveredServiceTracker.java
cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/ServicePublication.java
cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/DiscoveredServiceNotification.java
cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/DiscoveredServiceTracker.java
cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/ServicePublication.java
Removed:
cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/FindServiceCallback.java
cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/ServiceListener.java
Modified:
cxf/sandbox/dosgi/discovery/local/pom.xml
cxf/sandbox/dosgi/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/LocalDiscoveryService.java
cxf/sandbox/dosgi/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/ServiceEndpointDescriptionImpl.java
cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/Discovery.java
cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/ServiceEndpointDescription.java
cxf/sandbox/dosgi/dsw/cxf-dsw/pom.xml
cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/OsgiUtils.java
cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/AbstractPojoConfigurationTypeHandler.java
cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/ClientServiceFactory.java
cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/HttpServiceConfigurationTypeHandler.java
cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/PojoConfigurationTypeHandler.java
cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/WsdlConfigurationTypeHandler.java
cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/AbstractClientHook.java
cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/AbstractHook.java
cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/CxfListenerHook.java
cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/CxfPublishHook.java
cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/ServiceHookUtils.java
cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/ServiceEndpointDescriptionImpl.java
cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/Discovery.java
cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/ServiceEndpointDescription.java
cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/ActivatorTest.java
cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/TestUtils.java
cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/BundleTestContext.java
cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/CxfListenerHookTest.java
cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/CxfPublishHookTest.java
cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/ServiceHookUtilsTest.java
Modified: cxf/sandbox/dosgi/discovery/local/pom.xml
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/discovery/local/pom.xml?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/discovery/local/pom.xml (original)
+++ cxf/sandbox/dosgi/discovery/local/pom.xml Wed Jan 28 17:16:16 2009
@@ -38,7 +38,7 @@
<bundle.import.package>*</bundle.import.package>
<bundle.export.package>
org.apache.cxf.dosgi.discovery.local.*;version="${pom.version}",
- org.osgi.service.discovery;version="4.2.0";-split-package:=merge-first
+ org.osgi.service.discovery;version="1.0";-split-package:=merge-first
</bundle.export.package>
</properties>
Modified: cxf/sandbox/dosgi/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/LocalDiscoveryService.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/LocalDiscoveryService.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/LocalDiscoveryService.java (original)
+++ cxf/sandbox/dosgi/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/LocalDiscoveryService.java Wed Jan 28 17:16:16 2009
@@ -32,6 +32,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
@@ -45,11 +46,18 @@
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.Filter;
+import org.osgi.framework.ServiceReference;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.service.discovery.Discovery;
-import org.osgi.service.discovery.FindServiceCallback;
+import org.osgi.service.discovery.DiscoveredServiceNotification;
+import org.osgi.service.discovery.DiscoveredServiceTracker;
import org.osgi.service.discovery.ServiceEndpointDescription;
-import org.osgi.service.discovery.ServiceListener;
+import org.osgi.util.tracker.ServiceTracker;
+
+import static org.osgi.service.discovery.DiscoveredServiceNotification.AVAILABLE;
+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 LocalDiscoveryService implements Discovery {
@@ -71,30 +79,64 @@
private static final String PROPERTY_ELEMENT = "property";
private static final String PROPERTY_KEY_ATTRIBUTE = "name";
- // TODO : these properties should be configurable
- private static final long ASYNC_WAIT_TIME = 5000L;
+ // TODO : this property should be configurable
private static final long CONFIG_CHECK_TIME = 5000L;
// this is effectively a set which allows for multiple service descriptions with the
// same interface name but different properties and takes care of itself with respect to concurrency
private ConcurrentHashMap<ServiceEndpointDescription, ServiceEndpointDescription> servicesInfo =
new ConcurrentHashMap<ServiceEndpointDescription, ServiceEndpointDescription>();
- private ConcurrentHashMap<ServiceListener, Filter> listeners =
- new ConcurrentHashMap<ServiceListener, Filter>();
+ private Map<ServiceEndpointDescription, ServiceEndpointDescription> oldServicesInfo =
+ new HashMap<ServiceEndpointDescription, ServiceEndpointDescription>();
+ private Map<ServiceEndpointDescription, ServiceEndpointDescription> newServicesInfo =
+ new HashMap<ServiceEndpointDescription, ServiceEndpointDescription>();
+ private Map<String, List<DiscoveredServiceTracker>> interfacesToTrackers =
+ new HashMap<String, List<DiscoveredServiceTracker>>();
+ private Map<String, List<DiscoveredServiceTracker>> filtersToTrackers =
+ new HashMap<String, List<DiscoveredServiceTracker>>();
+ private Map<DiscoveredServiceTracker, Collection> trackersToInterfaces =
+ new HashMap<DiscoveredServiceTracker, Collection>();
+ private Map<DiscoveredServiceTracker, Collection> trackersToFilters =
+ new HashMap<DiscoveredServiceTracker, Collection>();
private BundleContext bc;
private boolean attachedToBundle;
private boolean isShutdown;
- private BlockingQueue<Callable<Boolean>> asyncChecks
- = new LinkedBlockingQueue<Callable<Boolean>>();
- private Thread asyncChecksThread;
private Thread configChecksThread;
private long lastConfigModification;
+ private ServiceTracker trackerTracker;
public LocalDiscoveryService(BundleContext bc) {
this.bc = bc;
readMetadata();
+
+ // track the registration of DiscoveredServiceTrackers
+ trackerTracker =
+ new ServiceTracker(bc,
+ DiscoveredServiceTracker.class.getName(),
+ null) {
+ public Object addingService(ServiceReference reference) {
+ Object result = super.addingService(reference);
+ cacheTracker(reference, result);
+ return result;
+ }
+
+ public void modifiedService(ServiceReference reference,
+ Object service) {
+ super.modifiedService(reference, service);
+ updateTracker(reference, service);
+ }
+
+ public void removedService(ServiceReference reference,
+ Object service) {
+ super.removedService(reference, service);
+ clearTracker(service);
+ }
+ };
+
+ trackerTracker.open();
+
if (!attachedToBundle) {
configChecksThread = new Thread(new ConfigCheckRunnable());
configChecksThread.start();
@@ -103,119 +145,186 @@
public void updateProperties(Dictionary props) {
}
-
- public void addServiceListener(ServiceListener sl, String filter) {
- listeners.put(sl, createFilter(filter));
- }
-
- public void addServiceListener(ServiceListener sl) {
- listeners.put(sl, null);
- }
- public void removeServiceListener(ServiceListener sl) {
- listeners.remove(sl);
- }
-
- public Collection /*<ServiceEndpointDescription>*/ findService(String interfaceName, String filter) {
- return findServiceWithFilter(interfaceName, createFilter(filter));
- }
-
- public void findService(String interfaceName, String filter, FindServiceCallback listener) {
- Filter f = createFilter(filter);
- if (f != null) {
- doFindService(interfaceName, f, listener);
+ private synchronized void cacheTracker(ServiceReference reference,
+ Object service) {
+ if (service instanceof DiscoveredServiceTracker) {
+ DiscoveredServiceTracker tracker =
+ (DiscoveredServiceTracker)service;
+ Collection interfaces =
+ addTracker(reference,
+ tracker,
+ PROP_KEY_MATCH_CRITERIA_INTERFACES,
+ interfacesToTrackers,
+ trackersToInterfaces);
+ Collection filters =
+ addTracker(reference,
+ tracker,
+ PROP_KEY_MATCH_CRITERIA_FILTERS,
+ filtersToTrackers,
+ trackersToFilters);
+
+ triggerCallbacks(null, interfaces, tracker, false);
+ triggerCallbacks(null, filters, tracker, true);
+ }
+ }
+
+ private synchronized void updateTracker(ServiceReference reference,
+ Object service) {
+ if (service instanceof DiscoveredServiceTracker) {
+ DiscoveredServiceTracker tracker =
+ (DiscoveredServiceTracker)service;
+ LOG.info("updating tracker: " + tracker);
+ Collection oldInterfaces = removeTracker(tracker,
+ interfacesToTrackers,
+ trackersToInterfaces);
+ Collection oldFilters = removeTracker(tracker,
+ filtersToTrackers,
+ trackersToFilters);
+
+ Collection newInterfaces =
+ addTracker(reference,
+ tracker,
+ PROP_KEY_MATCH_CRITERIA_INTERFACES,
+ interfacesToTrackers,
+ trackersToInterfaces);
+ Collection newFilters =
+ addTracker(reference,
+ tracker,
+ PROP_KEY_MATCH_CRITERIA_FILTERS,
+ filtersToTrackers,
+ trackersToFilters);
+
+ triggerCallbacks(oldInterfaces, newInterfaces, tracker, false);
+ triggerCallbacks(oldFilters, newFilters, tracker, true);
+ }
+ }
+
+ private synchronized void clearTracker(Object service) {
+ if (service instanceof DiscoveredServiceTracker) {
+ removeTracker((DiscoveredServiceTracker)service,
+ interfacesToTrackers,
+ trackersToInterfaces);
+ removeTracker((DiscoveredServiceTracker)service,
+ filtersToTrackers,
+ trackersToFilters);
+ }
+ }
+
+ private Collection addTracker(
+ ServiceReference reference,
+ DiscoveredServiceTracker tracker,
+ String property,
+ Map<String, List<DiscoveredServiceTracker>> forwardMap,
+ Map<DiscoveredServiceTracker, Collection> reverseMap) {
+ Collection collection =
+ (Collection)reference.getProperty(property);
+ LOG.info("adding tracker: " + tracker + " collection: " + collection + " registered against prop: " + property);
+ if (nonEmpty(collection)) {
+ reverseMap.put(tracker, collection);
+ Iterator i = collection.iterator();
+ while (i.hasNext()) {
+ String element = (String)i.next();
+ if (forwardMap.containsKey(element)) {
+ forwardMap.get(element).add(tracker);
+ } else {
+ List<DiscoveredServiceTracker> trackerList =
+ new ArrayList<DiscoveredServiceTracker>();
+ trackerList.add(tracker);
+ forwardMap.put(element, trackerList);
+ }
+ }
}
+ return collection;
}
-
- @SuppressWarnings("unchecked")
- private Collection<ServiceEndpointDescription> findServiceWithFilter(
- String interfaceName, Filter f) {
- if (f == null) {
- return Collections.emptyList();
- }
-
- List<ServiceEndpointDescription> sds = new ArrayList<ServiceEndpointDescription>();
-
- for (ServiceEndpointDescription sd : servicesInfo.values()) {
- if (f.match(getServiceProperties(interfaceName, sd))) {
- sds.add(sd);
+
+ private Collection removeTracker(
+ DiscoveredServiceTracker tracker,
+ Map<String, List<DiscoveredServiceTracker>> forwardMap,
+ Map<DiscoveredServiceTracker, Collection> reverseMap) {
+ Collection collection = reverseMap.get(tracker);
+ if (nonEmpty(collection)) {
+ reverseMap.remove(tracker);
+ Iterator i = collection.iterator();
+ while (i.hasNext()) {
+ String element = (String)i.next();
+ if (forwardMap.containsKey(element)) {
+ forwardMap.get(element).remove(tracker);
+ }
}
}
- return sds;
+ return collection;
}
-
-
- private void doFindService(final String interfaceName, final Filter f,
- final FindServiceCallback listener) {
- if (attachedToBundle) {
- checkServices(interfaceName, f, listener);
- return;
- }
-
- synchronized (this) {
- if (isShutdown) {
- return;
- }
- if (asyncChecksThread == null) {
- asyncChecksThread = new Thread(new AsyncCheckRunnable());
- asyncChecksThread.start();
+
+ private void triggerCallbacks(Collection oldInterest,
+ Collection newInterest,
+ DiscoveredServiceTracker tracker,
+ boolean isFilter) {
+ // compute delta between old & new interfaces/filters and
+ // trigger callbacks for any entries in servicesInfo that
+ // match any *additional* interface/filters
+ Collection deltaInterest = new ArrayList();
+ if (nonEmpty(newInterest)) {
+ if (isEmpty(oldInterest)) {
+ deltaInterest.addAll(newInterest);
+ } else {
+ Iterator i = newInterest.iterator();
+ while (i.hasNext()) {
+ String next = (String)i.next();
+ if (!oldInterest.contains(next)) {
+ deltaInterest.add(next);
+ }
+ }
}
}
- asyncChecks.add(new Callable<Boolean>() {
- public Boolean call() throws Exception {
- return checkServices(interfaceName, f, listener);
- }
-
- });
- }
-
- private boolean checkServices(String interfaceName, Filter f, FindServiceCallback listener) {
- Collection<ServiceEndpointDescription> sds =
- findServiceWithFilter(interfaceName, f);
- if (sds.isEmpty()) {
- return false;
+ if (servicesInfo.size() > 0) {
+ LOG.info("search for matches to trigger callbacks with delta: " + deltaInterest);
} else {
- listener.servicesFound(sds);
- return true;
+ LOG.info("nothing to search for matches to trigger callbacks with delta: " + deltaInterest);
+ }
+ Iterator i = deltaInterest.iterator();
+ while (i.hasNext()) {
+ String next = (String)i.next();
+ for (ServiceEndpointDescription sd : servicesInfo.values()) {
+ LOG.info("check if next: " + next + (isFilter ? " matches " : " contained by ") + sd.getProvidedInterfaces());
+ if ((isFilter && filterMatches(next, sd))
+ || sd.getProvidedInterfaces().contains(next)) {
+ tracker.serviceChanged(new TrackerNotification(sd,
+ AVAILABLE));
+ }
+ }
}
}
-
- public ServiceEndpointDescription publishService(Map javaInterfaces,
- Map endpointInterfaces,
- Map properties) {
- return publishService(javaInterfaces, endpointInterfaces, properties, true);
-
+
+ private static boolean nonEmpty(Collection c) {
+ return c != null && c.size() > 0;
}
-
- @SuppressWarnings("unchecked")
- public ServiceEndpointDescription publishService(Map javaInterfaces,
- Map endpointInterfaces,
- Map properties,
- boolean autoPublish) {
- ServiceEndpointDescriptionImpl sd = new ServiceEndpointDescriptionImpl(javaInterfaces,
- endpointInterfaces,
- properties);
- servicesInfo.putIfAbsent(sd, sd);
- for (Map.Entry<ServiceListener, Filter> entry : listeners.entrySet()) {
- if (entry.getValue() == null
- || entry.getValue().match(getServiceProperties(null, sd))) {
- entry.getKey().serviceAvailable(sd);
- }
- }
- return sd;
- }
-
- public void unpublishService(ServiceEndpointDescription sd) {
- servicesInfo.remove(sd);
- for (Map.Entry<ServiceListener, Filter> entry : listeners.entrySet()) {
- if (entry.getValue() == null
- || entry.getValue().match(getServiceProperties(null, sd))) {
- entry.getKey().serviceUnavailable(sd);
- }
+
+ private static boolean isEmpty(Collection c) {
+ return c == null || c.size() == 0;
+ }
+
+ private static class TrackerNotification
+ implements DiscoveredServiceNotification {
+
+ private ServiceEndpointDescription sd;
+ private int type;
+
+ TrackerNotification(ServiceEndpointDescription sd, int type) {
+ this.sd = sd;
+ this.type = type;
+ }
+
+ public ServiceEndpointDescription getServiceEndpointDescription() {
+ return sd;
}
- }
+ public int getType() {
+ return type;
+ }
+ }
+
private void readMetadata() {
InputStream is = getRemoteServicesStream();
@@ -236,8 +345,7 @@
}
private InputStream getRemoteServicesStream() {
-
-
+
// check default location
File f = new File(System.getProperty("user.dir") + DEFAULT_SERVICES_LOCATION);
if (f.exists()) {
@@ -270,8 +378,6 @@
return null;
}
-
-
@SuppressWarnings("unchecked")
private void readRemoteServices(InputStream is) throws Exception {
@@ -279,20 +385,81 @@
Namespace ns = Namespace.getNamespace(REMOTE_SERVICES_NS);
List<Element> references = d.getRootElement().getChildren(SERVICE_DESCRIPTION_ELEMENT, ns);
+ Set<ServiceEndpointDescription> keys = servicesInfo.keySet();
+ for (ServiceEndpointDescription sd : keys) {
+ oldServicesInfo.put(sd, sd);
+ }
servicesInfo.clear();
for (Element ref : references) {
- List<String> iNames = getInterfaceNames(ref.getChildren(PROVIDE_INTERFACE_ELEMENT, ns));
+ List<String> iNames = getProvidedInterfaces(ref.getChildren(PROVIDE_INTERFACE_ELEMENT, ns));
if (iNames.isEmpty()) {
continue;
}
ServiceEndpointDescription sd = new ServiceEndpointDescriptionImpl(iNames,
getProperties(ref.getChildren(PROPERTY_ELEMENT, ns)));
+ LOG.info("retrieved remote-service info for: " + sd.getProvidedInterfaces());
servicesInfo.putIfAbsent(sd, sd);
+ if (!oldServicesInfo.containsKey(sd)) {
+ newServicesInfo.put(sd, sd);
+ } else {
+ oldServicesInfo.remove(sd);
+ }
}
- }
+ triggerCallbacks();
+ }
+
+ private void triggerCallbacks() {
+ // REVISIT: generating modified callbacks for interface elements with
+ // modified properties is problematic since multiple interface elements
+ // with the same provides attribute are currently considered to
+ // represent distinct service instances
+
+ // iterate over oldServicesInfo generating unavailable callbacks for
+ // completely removed service instances
+ triggerNotificationsFor(oldServicesInfo, UNAVAILABLE);
+
+
+ // iterate over newServicesInfo generating added callbacks for
+ // new services
+ triggerNotificationsFor(newServicesInfo, AVAILABLE);
+ }
+
+ private void triggerNotificationsFor(Map<ServiceEndpointDescription, ServiceEndpointDescription> sds, int type) {
+ Set<ServiceEndpointDescription> keys = sds.keySet();
+ for (ServiceEndpointDescription sd : keys) {
+ Iterator interfaces = interfacesToTrackers.keySet().iterator();
+ while (interfaces.hasNext()) {
+ String next = (String)interfaces.next();
+ // REVISIT: shouldn't the notification include some indication
+ // of which interface name (or filter) fired the match?
+ if (sd.getProvidedInterfaces().contains(next)) {
+ List<DiscoveredServiceTracker> trackers =
+ interfacesToTrackers.get(next);
+ for (DiscoveredServiceTracker tracker : trackers) {
+ tracker.serviceChanged(new TrackerNotification(sd,
+ type));
+ }
+ }
+ }
+
+ Iterator filters = filtersToTrackers.keySet().iterator();
+ while (filters.hasNext()) {
+ String next = (String)filters.next();
+ if (filterMatches(next, sd)) {
+ List<DiscoveredServiceTracker> trackers =
+ filtersToTrackers.get(next);
+ for (DiscoveredServiceTracker tracker : trackers) {
+ tracker.serviceChanged(new TrackerNotification(sd,
+ type));
+ }
+ }
+ }
+ }
+ sds.clear();
+ }
private Map<String, Object> getProperties(List<Element> elementProps) {
@@ -308,7 +475,7 @@
return props;
}
- private static List<String> getInterfaceNames(List<Element> elements) {
+ private static List<String> getProvidedInterfaces(List<Element> elements) {
List<String> names = new ArrayList<String>();
@@ -325,59 +492,12 @@
public void shutdown() {
synchronized (this) {
isShutdown = true;
- if (asyncChecksThread != null) {
- asyncChecksThread.interrupt();
- }
}
if (configChecksThread != null) {
configChecksThread.interrupt();
}
}
- private class AsyncCheckRunnable implements Runnable {
-
- public void run() {
- while (!Thread.currentThread().isInterrupted()) {
- try {
- // wait untill we have at least one task
- Callable<Boolean> task = asyncChecks.take();
- Collection<Callable<Boolean>> remainingTasks = null;
- if (asyncChecks.size() > 0) {
- remainingTasks =
- new ArrayList<Callable<Boolean>>(asyncChecks);
- } else {
- remainingTasks = Collections.emptyList();
- }
- // try the first task
- if (!tryTask(task)) {
- asyncChecks.add(task);
- }
-
- // try the rest
- for (Callable<Boolean> c : remainingTasks) {
- if (tryTask(c)) {
- asyncChecks.remove(c);
- }
- }
-
- Thread.sleep(ASYNC_WAIT_TIME);
- } catch (InterruptedException ex) {
- Thread.currentThread().interrupt();
- }
- }
-
- }
-
-
- private boolean tryTask(Callable<Boolean> task) {
- try {
- return task.call();
- } catch (Exception ex) {
- return false;
- }
- }
- }
-
private class ConfigCheckRunnable implements Runnable {
public void run() {
@@ -410,26 +530,34 @@
return null;
}
+ private boolean filterMatches(String filterValue,
+ ServiceEndpointDescription sd) {
+ Filter filter = createFilter(filterValue);
+ return filter != null
+ ? filter.match(getServiceProperties(null, sd))
+ : false;
+ }
+
@SuppressWarnings("unchecked")
private Dictionary<String, Object> getServiceProperties(String interfaceName,
ServiceEndpointDescription sd) {
Dictionary<String, Object> d = new Hashtable<String, Object>(sd.getProperties());
- String[] interfaceNames = getInterfaceNames(sd, interfaceName);
+ String[] interfaceNames = getProvidedInterfaces(sd, interfaceName);
if (interfaceNames != null) {
d.put(Constants.OBJECTCLASS, interfaceNames);
}
return d;
}
- private static String[] getInterfaceNames(ServiceEndpointDescription sd, String interfaceName) {
+ private static String[] getProvidedInterfaces(ServiceEndpointDescription sd, String interfaceName) {
- Collection interfaceNames = sd.getInterfaceNames();
+ Collection interfaceNames = sd.getProvidedInterfaces();
if (interfaceName == null) {
return null;
}
- Iterator iNames = interfaceNames.iterator();
+ Iterator iNames = interfaceNames.iterator();
while (iNames.hasNext()) {
if (iNames.next().equals(interfaceName)) {
return new String[]{interfaceName};
Modified: cxf/sandbox/dosgi/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/ServiceEndpointDescriptionImpl.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/ServiceEndpointDescriptionImpl.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/ServiceEndpointDescriptionImpl.java (original)
+++ cxf/sandbox/dosgi/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/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 =
@@ -54,13 +56,6 @@
properties = remoteProperties;
}
- public ServiceEndpointDescriptionImpl(Map<String, String> javaInterfaces,
- Map<String, String> endpointInterfaces,
- Map<String, Object> remoteProperties) {
- this.interfaceNames = new HashSet<String>(javaInterfaces.keySet());
- properties = remoteProperties;
- }
-
public Object getProperty(String key) {
return properties.get(key);
}
@@ -86,12 +81,12 @@
}
ServiceEndpointDescription other = (ServiceEndpointDescription)obj;
- 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;
}
@@ -105,15 +100,19 @@
return null;
}
- public Collection /*<String>*/ getInterfaceNames() {
+ public Collection /*<String>*/ getProvidedInterfaces() {
return interfaceNames;
}
- public String getProtocolSpecificInterfaceName(String interfaceName) {
+ public String getVersion(String interfaceName) {
+ return "0.0";
+ }
+
+ public String getEndpointInterfaceName(String interfaceName) {
return interfaceName;
}
- public String getVersion(String interfaceName) {
- return "0.0";
+ public String getEndpointID() {
+ return null;
}
}
Added: cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/DiscoveredServiceNotification.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/DiscoveredServiceNotification.java?rev=738547&view=auto
==============================================================================
--- cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/DiscoveredServiceNotification.java (added)
+++ cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/DiscoveredServiceNotification.java Wed Jan 28 17:16:16 2009
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) OSGi Alliance (2008). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.discovery;
+
+/**
+ * Interface for notification on discovered services.
+ *
+ * @version $Revision$
+ */
+public interface DiscoveredServiceNotification {
+
+ /**
+ * Notification indicating that a service matching the listening criteria has been
+ * discovered.
+ * <p>
+ * The value of <code>AVAILABLE</code> is 0x00000001.
+ */
+ public final static int AVAILABLE = 0x00000001;
+
+ /**
+ * Notification indicating that the properties of a previously discovered service
+ * have changed.
+ * <p>
+ * The value of <code>MODIFIED</code> is 0x00000002.
+ */
+ public final static int MODIFIED = 0x00000002;
+
+ /**
+ * Notification indicating that a previously discovered service is no longer known
+ * to discovery.
+ * <p>
+ * The value of <code>UNAVAILABLE</code> is 0x00000004.
+ */
+ public final static int UNAVAILABLE = 0x00000004;
+
+ /**
+ * Notification indicating that the properties of a previously discovered service
+ * have changed and the new properties no longer match the listener's
+ * filter.
+ * <p>
+ * The value of <code>MODIFIED_ENDMATCH</code> is 0x00000008.
+ */
+ public final static int MODIFIED_ENDMATCH = 0x00000008;
+
+ /**
+ * Returns information currently known to Discovery regarding the service
+ * endpoint.
+ * <p>
+ *
+ * @return metadata of the service this Discovery notifies about.
+ */
+ ServiceEndpointDescription getServiceEndpointDescription();
+
+ /**
+ * Returns the type of notification. The type values are:
+ * <ul>
+ * <li>{@link #AVAILABLE} </li> <li>{@link #MODIFIED} </li> <li>
+ * {@link #MODIFIED_ENDMATCH} </li> <li>{@link #UNAVAILABLE} </li>
+ * </ul>
+ *
+ * @return Type of notification regarding known service metadata.
+ */
+ int getType();
+}
Added: cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/DiscoveredServiceTracker.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/DiscoveredServiceTracker.java?rev=738547&view=auto
==============================================================================
--- cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/DiscoveredServiceTracker.java (added)
+++ cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/DiscoveredServiceTracker.java Wed Jan 28 17:16:16 2009
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) OSGi Alliance (2008). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.discovery;
+
+/**
+ * Interface of trackers for discovered remote services. <br>
+ * When such a service is registered with the framework, then {@link Discovery}
+ * will notify it about remote services matching one of the provided criteria
+ * and will keep notifying it on changes of information known to Discovery
+ * regarding this services.
+ *
+ * <code>Discovery</code> may deliver notifications on discovered services to a
+ * <code>DiscoveredServiceTracker</code> out of order and may concurrently call
+ * and/or reenter a <code>DiscoveredServiceTracker</code>.
+ *
+ * @version $Revision$
+ */
+public interface DiscoveredServiceTracker {
+
+ /**
+ * Property describing service interfaces this tracker is interested in.
+ * Value of this property is of type Collection (<? extends String>).<br>
+ * Property is optional, may be null.
+ */
+ public static final String PROP_KEY_MATCH_CRITERIA_INTERFACES = "osgi.discovery.interest.interfaces";
+
+ /**
+ * Property describing filters for services this tracker is interested in.
+ * Value of this property is of type Collection (<? extends String>). See
+ * {@link ServicePublication} for some standard property keys used to
+ * publish service metadata. <br>
+ * Property is optional, may be null.
+ */
+ public static final String PROP_KEY_MATCH_CRITERIA_FILTERS = "osgi.discovery.interest.filters";
+
+ /**
+ * Receives notification that information known to Discovery regarding a
+ * remote service has changed. <br>
+ * The tracker is only notified about remote services which fulfill the
+ * matching criteria, either one of the interfaces or one of the filters,
+ * provided as properties of this service.
+ *
+ * @param notification
+ * the <code>DiscoveredServiceNotification</code> object
+ * describing the change.
+ */
+ void serviceChanged(DiscoveredServiceNotification notification);
+}
Modified: cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/Discovery.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/Discovery.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/Discovery.java (original)
+++ cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/Discovery.java Wed Jan 28 17:16:16 2009
@@ -16,187 +16,42 @@
package org.osgi.service.discovery;
-import java.util.Collection;
-import java.util.Map;
-
/**
- * Interface of the Discovery service. This service allows to publish services
- * exposed for remote access as well as search for remote services. <BR>
+ * Discovery registers a service implementing this interface. This service is
+ * registered with extra properties identified at the beginning of this
+ * interface to denote the name of the product providing Discovery
+ * functionality, its version, vendor, used protocols etc..
+ *
+ * Discovery allows to publish services exposed for remote access as well as to
+ * search for remote services. Register a {@link ServicePublication} service in
+ * order to publish service metadata and or a {@link DiscoveredServiceTracker}
+ * service in order to search for remote services.<BR>
* Discovery service implementations usually rely on some discovery protocols or
* other information distribution means.
*
* @version $Revision$
*/
public interface Discovery {
- /**
- *
- */
- final String OSGI_DISCOVERY = "osgi.discovery";
-
- /**
- *
- */
- final String OSGI_DISCOVERY_NONE = "none";
-
- /**
- *
- */
- final String OSGI_DISCOVERY_AUTO_PUBLISH = "auto-publish";
-
- /**
- * Add a ServiceListener for a particular service description.
- *
- * @param filter
- * a filter to services to listen for. If filter is
- * <code>null</code> then all services are considered.
- * @param listener
- * which is to call when discovery detects changes in
- * availability or description of a service. The same listener
- * object may be used to listen on multiple service filters.
- * @throws IllegalArgumentException
- * if listener is null or if filter is invalid
- */
- void addServiceListener(ServiceListener listener, String filter);
-
- /**
- * This method is the same as calling
- * <code>Discovery.addServiceListener(ServiceListener listener, String filter)</code>
- * with <code>filter</code> set to <code>null</code>.
- *
- * @param listener
- * which is to call when discovery detects changes in
- * availability or description of a service. The same listener
- * object may be used to listen on multiple service filters.
- * @throws IllegalArgumentException
- * if listener is null
- * @see #addServiceListener(ServiceListener, String)
- */
- void addServiceListener(ServiceListener listener);
-
- /**
- * Removes a ServiceListener.
- *
- * @param listener
- * ServiceListener which should be removed. If that listener
- * object was registered several times then all registrations
- * will be removed. If that listener object haven't been added
- * before, then the method returns without throwing exceptions.
- */
- void removeServiceListener(ServiceListener listener);
-
- /**
- * Searches for services matching the provided interface name and filter.
- *
- * @param interfaceName
- * name of the interface that returned services have to provide.
- * If name is null then all services are considered to match.
- * @param filter
- * an LDAP filter which the service has to satisfy. If filter is
- * null all services are considered to match.
- * @return Collection of <code>ServiceEndpointDescription</code> objects
- * which were found to match interface name and filter. The
- * collection is empty if none was found. The collection represents
- * a snapshot and as such is not going to be updated in case other matching
- * services become available at a later point of time.
- */
- Collection /* <? extends ServiceEndpointDescription> */findService(
- String interfaceName, String filter);
-
- /**
- * Asynchronous version of <code>Discovery.findService(String interfaceName,
- * String filter)</code> method.
- *
- * @param interfaceName
- * name of the interface returned services have to provide. If
- * name is null then all services are considered to match.
- * @param filter
- * an LDAP filter which the service has to satisfy. Note that
- * <code>ServiceEndpointDescription</code> defines some
- * properties for service url, interface version etc.. If filter
- * is null all services are considered to match.
- * @param callback
- * to notify about the asynchronous response of the find
- * operation
- * @throws IllegalArgumentException
- * if callback is null
- * @see #findService(String, String)
- */
- void findService(String interfaceName, String filter,
- FindServiceCallback callback);
-
- /**
- * Publish the provided service meta-data.
- *
- * @param javaInterfacesAndVersions
- * names of java interfaces offered by the service and their
- * version. For every interface to publish you have to define its
- * version. If you don't have a version, put "0.0.0" in it.
- * @param javaInterfacesAndEndpointInterfaces
- * associates java interfaces to general end point interface
- * names. It is not needed to to have and end point interface for
- * a java interface. The map may be null.
- * @param properties
- * a bag of service properties (key-value pairs) to be published.
- * It may be null. Note that Discovery might make use of certain
- * standard properties like the ones defined by
- * {@link ServiceEndpointDescription} for the publication process
- * if they are provided.
- *
- * @return an instance of {@link ServiceEndpointDescription} or null if the
- * publishing failed
- *
- * @throws IllegalArgumentException
- * if javaInterfacesAndVersions is null or empty
- */
- ServiceEndpointDescription publishService(
- Map/* <String, String> */javaInterfacesAndVersions,
- Map/* <String, String> */javaInterfacesAndEndpointInterfaces,
- Map/* <String, Object> */properties);
-
- /**
- * Publish the provided service. The information is published by the
- * Discovery implementation.<b> If the parameter autopublish=true, the
- * Discovery implementation actively pushes the information about the
- * service to the network. Otherwise, it is just available upon request from
- * other Discovery implementations. The ServiceEndpointDescription is
- * matched using the Comparable interface.
- *
- * @param javaInterfacesAndVersions
- * its an association between interfaces and versions. For every
- * interface to publish you have to define its version. If you
- * don't have a version, put "0.0.0" in it.
- * @param javaInterfacesAndEndpointInterfaces
- * associates java interfaces to general end point interface
- * names. It is not needed to to have and end point interface for
- * a java interface. The map can be null.
- * @param properties
- * a bag of properties to be published; can be null
- * @param autopublish
- * if true, service information is actively pushed to the network
- * for discovery
- *
- * @return an instance of {@link ServiceEndpointDescription} or null if the
- * publishing failed
- *
- * @throws IllegalArgumentException
- * if javaInterfacesAndVersions is null or empty
- */
- ServiceEndpointDescription publishService(
- Map/* <String, String> */javaInterfacesAndVersions,
- Map/* <String, String> */javaInterfacesAndEndpointInterfaces,
- Map/* <String, Object> */properties, boolean autopublish);
-
- /**
- * Make the given service un-discoverable. The previous publish request for
- * a service is undone. The service information is also removed from the
- * local or global cache if cached before.
- *
- * @param serviceEndpointDescription
- * ServiceEndpointDescription of the service to unpublish. If
- * this ServiceEndpointDescription haven't been published before,
- * then the method returns without throwing exceptions.
- * @throws IllegalArgumentException
- * if serviceEndpointDescription is null or incomplete
- */
- void unpublishService(ServiceEndpointDescription serviceEndpointDescription);
+
+ /**
+ * Service Registration property for the name of the Discovery product.
+ */
+ static final String PROP_KEY_PRODUCT_NAME = "osgi.remote.discovery.product";
+
+ /**
+ * Service Registration property for the version of the Discovery product.
+ */
+ static final String PROP_KEY_PRODUCT_VERSION = "osgi.remote.discovery.product.version";
+
+ /**
+ * Service Registration property for the Discovery product vendor name.
+ */
+ static final String PROP_KEY_VENDOR_NAME = "osgi.remote.discovery.vendor";
+
+ /**
+ * Service Registration property that lists the discovery protocols used by
+ * this Discovery service. Value of this property is of type Collection (<?
+ * extends String>).
+ */
+ static final String PROP_KEY_SUPPORTED_PROTOCOLS = "osgi.remote.discovery.supported_protocols";
}
Modified: cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/ServiceEndpointDescription.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/ServiceEndpointDescription.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/ServiceEndpointDescription.java (original)
+++ cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/ServiceEndpointDescription.java Wed Jan 28 17:16:16 2009
@@ -21,96 +21,95 @@
import java.util.Map;
/**
- * The ServiceEndpointDescription interface describes an endpoint of a service.
- * This class can be considered as a wrapper around the property map associated
- * with a service and its endpoint. It provides an API to conveniently access
- * the most important properties of the service.
+ * This interface describes an endpoint of a service. This class can be
+ * considered as a wrapper around the property map of a published service and
+ * its endpoint. It provides an API to conveniently access the most important
+ * properties of the service.
*
* @version $Revision$
*/
public interface ServiceEndpointDescription {
- /**
- * If value of <code>getProtocolSpecificInterfaceName</code> needs to be
- * described as a key-value pair e.g. by the discovery protocol, filter for
- * discovery etc. and there is no other key standardized for that purpose
- * yet, then this is the recommended property key to use.
- */
- public final String PROP_KEY_PROTOCOL_SPECIFIC_INTERFACE_NAME = "protocol-specific-interface-name";
-
- /**
- * If value of <code>getVersion</code> needs to be described as a key-value
- * pair e.g. by the discovery protocol, filter for discovery etc. and there
- * is no other key standardized for that purpose yet, then this is the
- * recommended property key to use.
- */
- public final String PROP_KEY_VERSION = "version";
-
- /**
- * If value of <code>getServiceLocation</code> needs to be described as a
- * key-value pair e.g. by the discovery protocol, filter for discovery etc.
- * and there is no other key standardized for that purpose yet, then this is
- * the recommended property key to use.
- */
- public final String PROP_KEY_SERVICE_LOCATION = "location";
-
- /**
- * @return full qualified service interface names provided by the advertised
- * service (endpoint). The collection is never null or
- * empty but contains at least one service interface.
- */
- Collection /* <? extends String> */getInterfaceNames();
-
- /**
- * @param interfaceName
- * for which its communication protocol specific version should
- * be returned. It might be for instance a web service interface
- * name. Though this information is usually contained in
- * according interface descriptions, e.g. a wsdl file, it can
- * optionally be provided here as well since discovery usually
- * doesn't read and interprets such accompanying descriptions.
- *
- * @return The protocol specific service interface name.
- */
- String getProtocolSpecificInterfaceName(String interfaceName);
-
- /**
- * @param interfaceName
- * for which its version should be returned.
- * @return The service interface/implementation version.
- */
- String getVersion(String interfaceName);
-
- /**
- * @return The URL of the service location.
- */
- URL getLocation();
-
- /**
- * Getter method for the property value of a given key.
- *
- * @param key
- * Name of the property
- * @return The property value, null if none is found for the given key
- */
- Object getProperty(String key);
-
- /**
- * @return <code>java.util.Collection</code> of property names available in
- * the ServiceEndpointDescription. The collection is never null or
- * empty but contains at least basic properties like objectClass for
- * the service interface. The collection represents a snapshot and
- * as such is not going to be updated in case properties were added
- * or removed at a later point of time.
- */
- Collection/* <? extends String> */getPropertyKeys();
-
- /**
- * @return Returns all properties of the service as a
- * <code>java.util.Map</code>. The map is never null or empty but
- * contains at least basic properties like objectClass for the
- * service interface. The collection represents a snapshot and as
- * such is not going to be updated in case properties were added or
- * removed at a later point of time.
- */
- Map/* <String, Object> */getProperties();
+
+ /**
+ * Returns the value of the property with key
+ * {@link ServicePublication#PROP_KEY_SERVICE_INTERFACE_NAME}.
+ *
+ * @return service interface names provided by the advertised service
+ * (endpoint). The collection is never null or empty but contains at
+ * least one service interface.
+ */
+ Collection /* <? extends String> */getProvidedInterfaces();
+
+ /**
+ * Returns non-Java endpoint interface name associated with the given
+ * interface. Value of the property with key
+ * {@link ServicePublication#PROP_KEY_ENDPOINT_INTERFACE_NAME} is used by
+ * this operation.
+ *
+ * @param interfaceName
+ * for which its non-Java endpoint interface name should be
+ * returned.
+ *
+ * @return non-Java endpoint interface name. Null, if it hasn't been
+ * provided.
+ */
+ String getEndpointInterfaceName(String interfaceName);
+
+ /**
+ * Returns version of the given interface. Value of the property with key
+ * {@link ServicePublication#PROP_KEY_SERVICE_INTERFACE_VERSION} is used by
+ * this operation.
+ *
+ * @param interfaceName
+ * for which its version should be returned.
+ * @return Version of given service interface. Null, if it hasn't been
+ * provided.
+ */
+ String getVersion(String interfaceName);
+
+ /**
+ * Returns the value of the property with key
+ * {@link ServicePublication#PROP_KEY_ENDPOINT_LOCATION}.
+ *
+ * @return The URL of the service location. Null, if it hasn't been
+ * provided.
+ */
+ URL getLocation();
+
+ /**
+ * Returns the value of the property with key
+ * {@link ServicePublication#PROP_KEY_ENDPOINT_ID}.
+ *
+ * @return Unique id of service endpoint. Null, if it hasn't been provided.
+ */
+ String getEndpointID();
+
+ /**
+ * Getter method for the property value of a given key.
+ *
+ * @param key
+ * Name of the property
+ * @return The property value, null if none is found for the given key
+ */
+ Object getProperty(String key);
+
+ /**
+ * @return <code>java.util.Collection</code> of property names available in
+ * the ServiceEndpointDescription. The collection is never null or
+ * empty but contains at least basic properties like objectClass for
+ * the service interface. The collection represents a snapshot and
+ * as such is not going to be updated in case properties were added
+ * or removed at a later point of time.
+ */
+ Collection/* <? extends String> */getPropertyKeys();
+
+ /**
+ * @return Returns all properties of the service as a
+ * <code>java.util.Map</code>. The map is never null or empty but
+ * contains at least basic properties like objectClass for the
+ * service interface. The collection represents a snapshot and as
+ * such is not going to be updated in case properties were added or
+ * removed at a later point of time.
+ */
+ Map/* <String, Object> */getProperties();
}
Added: cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/ServicePublication.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/ServicePublication.java?rev=738547&view=auto
==============================================================================
--- cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/ServicePublication.java (added)
+++ cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/ServicePublication.java Wed Jan 28 17:16:16 2009
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) OSGi Alliance (2008). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.discovery;
+
+/**
+ * Register a service implementing the <code>ServicePublication</code> interface
+ * in order to publish metadata of a particular service (endpoint) via
+ * Discovery. Metadata which has to be published is given in form of properties
+ * at registration. <br>
+ * In order to update published service metadata, update the properties
+ * registered with the <code>ServicePublication</code> service. Depending on
+ * Discovery's implementation and underlying protocol it may result in an update
+ * or new re-publication of the service. <br>
+ * In order to unpublish the previously published service metadata, unregister
+ * the <code>ServicePublication</code> service.<br>
+ *
+ * Please note that providing the {@link #PROP_KEY_SERVICE_INTERFACE_NAME}
+ * property is mandatory when a <code>ServicePublication</code> service is
+ * registered.<br>
+ *
+ * Also important is that it's not guaranteed that after registering a
+ * <code>ServicePublication</code> object its service metadata is actually
+ * published. Beside the fact that at least one Discovery service has to be
+ * present, the provided properties have to be valid, e.g. shouldn't contain
+ * case variants of the same key name, a supported publication strategy used and
+ * the actual publication via Discovery mechanisms has to succeed.
+ *
+ * @version $Revision$
+ */
+public interface ServicePublication {
+
+ /**
+ * Mandatory ServiceRegistration property which contains a collection of
+ * full qualified interface names offered by the advertised service
+ * endpoint. Value of this property is of type Collection (<? extends
+ * String>).
+ */
+ public static final String PROP_KEY_SERVICE_INTERFACE_NAME = "service.interface";
+
+ /**
+ * Optional ServiceRegistration property which contains a collection of
+ * interface names with their associated version attributes separated by
+ * {@link #SEPARATOR} e.g. 'my.company.foo:1.3.5 my.company.zoo:2.3.5'. In
+ * case no version has been provided for an interface, Discovery may use the
+ * String-value of <code>org.osgi.framework.Version.emptyVersion</code>
+ * constant. <br>
+ * Value of this property is of type Collection (<? extends String>).
+ */
+ public static final String PROP_KEY_SERVICE_INTERFACE_VERSION = "service.interface.version";
+
+ /**
+ * Optional ServiceRegistration property which contains a collection of
+ * interface names with their associated (non-Java) endpoint interface names
+ * separated by {@link #SEPARATOR} e.g.:<br>
+ * 'my.company.foo:MyWebService my.company.zoo:MyWebService'.<br>
+ * This (non-Java) endpoint interface name is usually a communication
+ * protocol specific interface, for instance a web service interface name.
+ * Though this information is usually contained in accompanying properties
+ * e.g. a wsdl file, Discovery usually doesn't read and interprets such
+ * service meta-data. Providing this information explicitly, might allow
+ * external non-Java applications find services based on this endpoint
+ * interface.
+ *
+ * Value of this property is of type Collection (<? extends String>).
+ */
+ public static final String PROP_KEY_ENDPOINT_INTERFACE_NAME = "osgi.remote.endpoint.interface";
+
+ /**
+ * Optional ServiceRegistration property which contains a map of properties
+ * of the published service. <br>
+ * Property keys are handled in a case insensitive manner (as OSGi Framework
+ * does). Note that Discovery might make use of certain standard properties
+ * e.g. defined by {@link ServiceEndpointDescription} for the publication
+ * process if they are provided.<br>
+ * Value of this property is of type <code>java.util.Map<code>.
+ */
+ public static final String PROP_KEY_SERVICE_PROPERTIES = "service.properties";
+
+ /**
+ * Optional property of the published service identifying its location.
+ * Value of this property is of type <code>java.net.URL<code>.
+ */
+ public static final String PROP_KEY_ENDPOINT_LOCATION = "osgi.remote.endpoint.location";
+
+ /**
+ * Optional property of the published service uniquely identifying its
+ * endpoint. Value of this property is of type <code>String<code>.
+ */
+ public static final String PROP_KEY_ENDPOINT_ID = "osgi.remote.endpoint.id";
+
+ /**
+ * Separator for key value pairs.
+ */
+ public static final String SEPARATOR = ":";
+}
Modified: cxf/sandbox/dosgi/dsw/cxf-dsw/pom.xml
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/pom.xml?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/pom.xml (original)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/pom.xml Wed Jan 28 17:16:16 2009
@@ -38,7 +38,7 @@
<bundle.export.package>
org.apache.cxf.dosgi.*;version="${pom.version}",
org.osgi.service.distribution;version="4.2.0";-split-package:=merge-first,
- org.osgi.service.discovery;version="4.2.0";-split-package:=merge-first
+ org.osgi.service.discovery;version="1.0";-split-package:=merge-first
</bundle.export.package>
</properties>
Modified: cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/OsgiUtils.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/OsgiUtils.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/OsgiUtils.java (original)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/OsgiUtils.java Wed Jan 28 17:16:16 2009
@@ -113,7 +113,7 @@
List<ServiceEndpointDescription> srefs = new ArrayList<ServiceEndpointDescription>();
Namespace ns = Namespace.getNamespace(REMOTE_SERVICES_NS);
for (Element ref : references) {
- List<String> iNames = getInterfaceNames(ref.getChildren(PROVIDE_INTERFACE_ELEMENT, ns));
+ List<String> iNames = getProvidedInterfaces(ref.getChildren(PROVIDE_INTERFACE_ELEMENT, ns));
if (!serviceNamesMatch(names, iNames, matchAllNames)) {
continue;
}
@@ -134,7 +134,7 @@
List<ServiceEndpointDescription> srefs = new ArrayList<ServiceEndpointDescription>();
Namespace ns = Namespace.getNamespace(REMOTE_SERVICES_NS);
for (Element ref : references) {
- List<String> iNames = getInterfaceNames(ref.getChildren(PROVIDE_INTERFACE_ELEMENT, ns));
+ List<String> iNames = getProvidedInterfaces(ref.getChildren(PROVIDE_INTERFACE_ELEMENT, ns));
Map<String, Object> remoteProps = getProperties(ref.getChildren(PROPERTY_ELEMENT, ns));
srefs.add(new ServiceEndpointDescriptionImpl(iNames, remoteProps));
}
@@ -144,12 +144,12 @@
public static ServiceEndpointDescription[] flattenServiceDescription(ServiceEndpointDescription sd) {
ServiceEndpointDescription[] list = null;
- int interfaceNameCount = sd.getInterfaceNames().size();
- if (sd.getInterfaceNames() == null || interfaceNameCount <= 1) {
+ int interfaceNameCount = sd.getProvidedInterfaces().size();
+ if (sd.getProvidedInterfaces() == null || interfaceNameCount <= 1) {
list = new ServiceEndpointDescription[] {sd};
} else {
String[] iNames = (String[])
- sd.getInterfaceNames().toArray(new String[interfaceNameCount]);
+ sd.getProvidedInterfaces().toArray(new String[interfaceNameCount]);
list = new ServiceEndpointDescription[iNames.length];
for (int i = 0; i < iNames.length; i++) {
Map<String, Object> props =
@@ -177,10 +177,10 @@
}
private static Map<String, Object> excludeProperty(Map properties,
- String exlcude) {
+ String exclude) {
Map<String, Object> pruned = new HashMap<String, Object>();
for (Object key : properties.keySet()) {
- if (key.equals(exlcude)) {
+ if (key.equals(exclude)) {
} else {
pruned.put((String)key, properties.get(key));
}
@@ -266,7 +266,7 @@
props.put(key, sd.getProperty(key.toString()));
}
}
- String[] interfaceNames = getInterfaceNames(sd, interfaceName);
+ String[] interfaceNames = getProvidedInterfaces(sd, interfaceName);
if (interfaceNames != null) {
props.put(org.osgi.framework.Constants.OBJECTCLASS,
interfaceNames);
@@ -274,11 +274,11 @@
return filter.match(props);
}
- public static String[] getInterfaceNames(ServiceEndpointDescription sd, String interfaceName) {
+ public static String[] getProvidedInterfaces(ServiceEndpointDescription sd, String interfaceName) {
- int interfaceNameCount = sd.getInterfaceNames().size();
+ int interfaceNameCount = sd.getProvidedInterfaces().size();
String[] interfaceNames = (String[])
- sd.getInterfaceNames().toArray(new String[interfaceNameCount]);
+ sd.getProvidedInterfaces().toArray(new String[interfaceNameCount]);
if (interfaceName == null) {
return interfaceNames;
}
@@ -342,7 +342,7 @@
return props;
}
- private static List<String> getInterfaceNames(List<Element> elements) {
+ private static List<String> getProvidedInterfaces(List<Element> elements) {
List<String> names = new ArrayList<String>();
Modified: cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/AbstractPojoConfigurationTypeHandler.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/AbstractPojoConfigurationTypeHandler.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/AbstractPojoConfigurationTypeHandler.java (original)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/AbstractPojoConfigurationTypeHandler.java Wed Jan 28 17:16:16 2009
@@ -43,6 +43,8 @@
import org.osgi.framework.BundleContext;
import org.osgi.service.discovery.ServiceEndpointDescription;
+import static org.osgi.service.discovery.ServicePublication.PROP_KEY_ENDPOINT_LOCATION;
+
public abstract class AbstractPojoConfigurationTypeHandler extends AbstractConfigurationHandler {
private static final Logger LOG = Logger.getLogger(AbstractPojoConfigurationTypeHandler.class.getName());
private static final String PROVIDED_INTENT_VALUE = "PROVIDED";
@@ -204,4 +206,10 @@
}
return intentMap;
}
+
+ protected void addAddressProperty(Map props, String address) {
+ if (props != null) {
+ props.put(PROP_KEY_ENDPOINT_LOCATION, address);
+ }
+ }
}
Modified: cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/ClientServiceFactory.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/ClientServiceFactory.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/ClientServiceFactory.java (original)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/ClientServiceFactory.java Wed Jan 28 17:16:16 2009
@@ -46,8 +46,8 @@
}
public Object getService(Bundle requestingBundle, ServiceRegistration sreg) {
- String interfaceName = sd.getInterfaceNames() != null && sd.getInterfaceNames().size() > 0
- ? (String)sd.getInterfaceNames().toArray()[0]
+ String interfaceName = sd.getProvidedInterfaces() != null && sd.getProvidedInterfaces().size() > 0
+ ? (String)sd.getProvidedInterfaces().toArray()[0]
: null;
try {
return handler.createProxy(sreg.getReference(),
Modified: cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/HttpServiceConfigurationTypeHandler.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/HttpServiceConfigurationTypeHandler.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/HttpServiceConfigurationTypeHandler.java (original)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/HttpServiceConfigurationTypeHandler.java Wed Jan 28 17:16:16 2009
@@ -96,10 +96,11 @@
}
Bus bus = cxf.getBus();
+ String address = constructAddress(contextRoot);
ServerFactoryBean factory = createServerFactoryBean();
factory.setBus(bus);
factory.setServiceClass(iClass);
- factory.setAddress("/");
+ factory.setAddress(address);
factory.getServiceFactory().setDataBinding(new AegisDatabinding());
factory.setServiceBean(serviceBean);
@@ -108,7 +109,8 @@
applyIntents(dswContext, callingContext, factory.getFeatures(), factory, sd);
Server server = factory.create();
- getDistributionProvider().addExposedService(serviceReference, registerPublication(server, intents, contextRoot));
+ getDistributionProvider().addExposedService(serviceReference, registerPublication(server, intents, address));
+ addAddressProperty(sd.getProperties(), address);
return server;
} catch (IntentUnsatifiedException iue) {
getDistributionProvider().intentsUnsatisfied(serviceReference);
@@ -116,9 +118,16 @@
}
}
- private Map<String, String> registerPublication(Server server, String[] intents, String contextRoot) {
+ private Map<String, String> registerPublication(Server server, String[] intents, String address) {
Map<String, String> publicationProperties = super.registerPublication(server, intents);
+
+ publicationProperties.put(Constants.POJO_ADDRESS_PROPERTY, address);
+
+ return publicationProperties;
+ }
+
+ private String constructAddress(String contextRoot) {
String port = null;
boolean https = false;
if ("true".equalsIgnoreCase(System.getProperty("org.osgi.service.http.secure.enabled"))) {
@@ -137,12 +146,9 @@
} catch (UnknownHostException e) {
hostName = "localhost";
}
-
- publicationProperties.put(Constants.POJO_ADDRESS_PROPERTY,
- getAddress(https ? "https" : "http", hostName, port, contextRoot));
- return publicationProperties;
- }
+ return getAddress(https ? "https" : "http", hostName, port, contextRoot);
+ }
private HttpService getHttpService() {
for (ServiceReference sr : httpServiceReferences) {
Modified: cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/PojoConfigurationTypeHandler.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/PojoConfigurationTypeHandler.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/PojoConfigurationTypeHandler.java (original)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/PojoConfigurationTypeHandler.java Wed Jan 28 17:16:16 2009
@@ -55,7 +55,7 @@
return null;
}
- LOG.info("Creating a " + sd.getInterfaceNames().toArray()[0]
+ LOG.info("Creating a " + sd.getProvidedInterfaces().toArray()[0]
+ " client, endpoint address is " + address);
try {
@@ -91,7 +91,7 @@
return null;
}
- LOG.info("Creating a " + sd.getInterfaceNames().toArray()[0]
+ LOG.info("Creating a " + sd.getProvidedInterfaces().toArray()[0]
+ " endpoint from CXF PublishHook, address is " + address);
ServerFactoryBean factory = createServerFactoryBean();
@@ -106,6 +106,7 @@
Server server = factory.create();
getDistributionProvider().addExposedService(serviceReference, registerPublication(server, intents));
+ addAddressProperty(sd.getProperties(), address);
return server;
} catch (IntentUnsatifiedException iue) {
getDistributionProvider().intentsUnsatisfied(serviceReference);
Modified: cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/WsdlConfigurationTypeHandler.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/WsdlConfigurationTypeHandler.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/WsdlConfigurationTypeHandler.java (original)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/WsdlConfigurationTypeHandler.java Wed Jan 28 17:16:16 2009
@@ -65,7 +65,7 @@
return null;
}
- LOG.info("Creating a " + sd.getInterfaceNames().toArray()[0] + " client, wsdl address is "
+ LOG.info("Creating a " + sd.getProvidedInterfaces().toArray()[0] + " client, wsdl address is "
+ OsgiUtils.getProperty(sd, Constants.WSDL_CONFIG_PREFIX));
String serviceNs = OsgiUtils.getProperty(sd, Constants.SERVICE_NAMESPACE);