You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by da...@apache.org on 2009/02/24 10:38:23 UTC
svn commit: r747315 - in /cxf/dosgi/trunk:
discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/
discovery/local/src/test/resources/
dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/
dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/ho...
Author: davidb
Date: Tue Feb 24 09:38:22 2009
New Revision: 747315
URL: http://svn.apache.org/viewvc?rev=747315&view=rev
Log:
Added support for the alternative syntax of the remote-services.xml file.
One syntax is with value attributes like this:
<service-description>
<provide interface="org.apache.cxf.dosgi.samples.greeter.GreeterService" />
<property name="osgi.remote.interfaces" value="*" />
<property name="osgi.remote.requires.intents" value="SOAP HTTP" />
<property name="osgi.remote.configuration.type" value="pojo" />
<property name="osgi.remote.configuration.pojo.address" value="http://localhost:9090/greeter" />
</service-description>
The other syntax is with value element content, like this:
<service-description>
<provide interface="org.apache.cxf.dosgi.samples.greeter.GreeterService" />
<property name="osgi.remote.interfaces">*</property>
<property name="osgi.remote.requires.intents">SOAP HTTP</property>
<property name="osgi.remote.configuration.type">pojo</property>
<property name="osgi.remote.configuration.pojo.address">http://localhost:9090/greeter</property>
</service-description>
Additionally, removed some old duplicated code from the local discovery service.
New unit and system tests added.
Added:
cxf/dosgi/trunk/dsw/cxf-dsw/src/test/resources/OSGI-INF/remote-service/alt-remote-services.xml (with props)
Removed:
cxf/dosgi/trunk/discovery/local/src/test/resources/
Modified:
cxf/dosgi/trunk/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/LocalDiscoveryService.java
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/OsgiUtils.java
cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/CxfPublishHookTest.java
cxf/dosgi/trunk/samples/greeter/client/src/main/resources/OSGI-INF/remote-service/remote-services.xml
cxf/dosgi/trunk/systests/multi_bundle_distro/src/test/resources/OSGI-INF/remote-service/remote-services.xml
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=747315&r1=747314&r2=747315&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 Tue Feb 24 09:38:22 2009
@@ -19,77 +19,41 @@
package org.apache.cxf.dosgi.discovery.local;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
+import static org.osgi.service.discovery.DiscoveredServiceNotification.AVAILABLE;
+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 java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.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;
-import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Logger;
-import org.jdom.Document;
-import org.jdom.Element;
-import org.jdom.Namespace;
-import org.jdom.input.SAXBuilder;
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.framework.ServiceReference;
import org.osgi.service.discovery.DiscoveredServiceNotification;
import org.osgi.service.discovery.DiscoveredServiceTracker;
+import org.osgi.service.discovery.Discovery;
import org.osgi.service.discovery.ServiceEndpointDescription;
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;
-
+@SuppressWarnings("unchecked")
public class LocalDiscoveryService implements Discovery {
private static final Logger LOG = Logger.getLogger(LocalDiscoveryService.class.getName());
-
-
- private static final String DEFAULT_SERVICES_LOCATION =
- "/discovery/conf/remote-services.xml";
- private static final String REMOTE_SERVICES_ENTRY =
- "/META-INF/remote-service/remote-services.xml";
- private static final String REMOTE_SERVICES_NS =
- "http://www.osgi.org/xmlns/sd/v1.0.0";
-
- private static final String SERVICE_DESCRIPTION_ELEMENT = "service-description";
-
- private static final String PROVIDE_INTERFACE_ELEMENT = "provide";
- private static final String PROVIDE_INTERFACE_NAME_ATTRIBUTE = "interface";
-
- private static final String PROPERTY_ELEMENT = "property";
- private static final String PROPERTY_KEY_ATTRIBUTE = "name";
-
- // 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 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 =
@@ -99,17 +63,11 @@
private Map<DiscoveredServiceTracker, Collection> trackersToFilters =
new HashMap<DiscoveredServiceTracker, Collection>();
private BundleContext bc;
-
- private boolean attachedToBundle;
- private boolean isShutdown;
-
- private Thread configChecksThread;
- private long lastConfigModification;
+
private ServiceTracker trackerTracker;
public LocalDiscoveryService(BundleContext bc) {
this.bc = bc;
- readMetadata();
// track the registration of DiscoveredServiceTrackers
trackerTracker =
@@ -136,11 +94,6 @@
};
trackerTracker.open();
-
- if (!attachedToBundle) {
- configChecksThread = new Thread(new ConfigCheckRunnable());
- configChecksThread.start();
- }
}
public void updateProperties(Dictionary props) {
@@ -324,198 +277,11 @@
return type;
}
}
-
- private void readMetadata() {
-
- InputStream is = getRemoteServicesStream();
- if (is != null) {
- try {
- readRemoteServices(is);
- } catch (Exception ex) {
- LOG.warning("Problem parsing remote-services.xml :"
- + ex.getMessage());
- } finally {
- try {
- is.close();
- } catch (IOException ex) {
- // ignore
- }
- }
- }
- }
-
- private InputStream getRemoteServicesStream() {
-
- // check default location
- File f = new File(System.getProperty("user.dir") + DEFAULT_SERVICES_LOCATION);
- if (f.exists()) {
- long lastModified = f.lastModified();
- if (lastModified == lastConfigModification) {
- return null;
- }
- lastConfigModification = lastModified;
-
- try {
- LOG.info("Found remote-services.xml at " + f.getAbsolutePath());
- return f.toURL().openStream();
- } catch (Exception ex) {
- LOG.warning("remote-services.xml at " + f.getAbsolutePath()
- + " can not be accessed");
- }
- }
-
- // check if remoteservices.xml are attached to this bundle
- URL resourceURL = bc.getBundle().getEntry(REMOTE_SERVICES_ENTRY);
- if (resourceURL != null) {
- try {
- InputStream is = resourceURL.openStream();
- attachedToBundle = true;
- return is;
- } catch (IOException ex) {
- LOG.warning("Problem accessing remote-services.xml class resource");
- }
- }
- return null;
- }
-
- @SuppressWarnings("unchecked")
- private void readRemoteServices(InputStream is) throws Exception {
-
- Document d = new SAXBuilder().build(is);
- 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 = 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) {
-
- Map<String, Object> props = new HashMap<String, Object>();
-
- for (Element p : elementProps) {
- String key = p.getAttributeValue(PROPERTY_KEY_ATTRIBUTE);
- if (key != null) {
- props.put(key, p.getTextTrim());
- }
- }
-
- return props;
- }
-
- private static List<String> getProvidedInterfaces(List<Element> elements) {
-
- List<String> names = new ArrayList<String>();
-
- for (Element p : elements) {
- String name = p.getAttributeValue(PROVIDE_INTERFACE_NAME_ATTRIBUTE);
- if (name != null) {
- names.add(name);
- }
- }
-
- return names;
- }
-
+
public void shutdown() {
trackerTracker.close();
-
- synchronized (this) {
- isShutdown = true;
- }
- if (configChecksThread != null) {
- configChecksThread.interrupt();
- }
}
-
- private class ConfigCheckRunnable implements Runnable {
-
- public void run() {
- while (!Thread.currentThread().isInterrupted()) {
- try {
- Thread.sleep(CONFIG_CHECK_TIME);
- readMetadata();
- } catch (InterruptedException ex) {
- Thread.currentThread().interrupt();
- }
- }
-
- }
- }
-
private Filter createFilter(String filterValue) {
if (filterValue == null) {
@@ -567,6 +333,5 @@
}
return null;
}
-
}
Modified: cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/OsgiUtils.java
URL: http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/OsgiUtils.java?rev=747315&r1=747314&r2=747315&view=diff
==============================================================================
--- cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/OsgiUtils.java (original)
+++ cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/OsgiUtils.java Tue Feb 24 09:38:22 2009
@@ -67,7 +67,8 @@
private static final String PROVIDE_INTERFACE_NAME_ATTRIBUTE = "interface";
private static final String PROPERTY_ELEMENT = "property";
- private static final String PROPERTY_KEY_ATTRIBUTE = "name";
+ private static final String PROPERTY_NAME_ATTRIBUTE = "name";
+ private static final String PROPERTY_VALUE_ATTRIBUTE = "value";
private static final String PROPERTY_INTERFACE_ATTRIBUTE = "interface";
private static final String INTERFACE_WILDCARD = "*";
@@ -329,13 +330,18 @@
Map<String, Object> props = new HashMap<String, Object>();
for (Element p : elements) {
- String key = p.getAttributeValue(PROPERTY_KEY_ATTRIBUTE);
+ String key = p.getAttributeValue(PROPERTY_NAME_ATTRIBUTE);
+ String value = p.getAttributeValue(PROPERTY_VALUE_ATTRIBUTE);
+ if (value == null) {
+ value = p.getTextTrim();
+ }
+
String iface = p.getAttributeValue(PROPERTY_INTERFACE_ATTRIBUTE);
if (key != null) {
props.put(iface == null || iface.length() == 0
? key
: key + INTERFACE_SEPARATOR + iface,
- p.getTextTrim());
+ value);
}
}
Modified: cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/CxfPublishHookTest.java
URL: http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/CxfPublishHookTest.java?rev=747315&r1=747314&r2=747315&view=diff
==============================================================================
--- cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/CxfPublishHookTest.java (original)
+++ cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/CxfPublishHookTest.java Tue Feb 24 09:38:22 2009
@@ -68,6 +68,13 @@
}
@Test
+ public void testPublishSingleInterfaceAltFormat() throws Exception {
+ String[] serviceNames = new String[]{TestService.class.getName()};
+ String[] addresses = new String[]{"http://localhost:9000/hello"};
+ doTestPublishHook("alt-remote-services.xml", serviceNames, addresses);
+ }
+
+ @Test
public void testPublishMultiInterface() throws Exception {
String[] serviceNames = new String[]{TestService.class.getName(),
AdditionalInterface.class.getName()};
Added: cxf/dosgi/trunk/dsw/cxf-dsw/src/test/resources/OSGI-INF/remote-service/alt-remote-services.xml
URL: http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-dsw/src/test/resources/OSGI-INF/remote-service/alt-remote-services.xml?rev=747315&view=auto
==============================================================================
--- cxf/dosgi/trunk/dsw/cxf-dsw/src/test/resources/OSGI-INF/remote-service/alt-remote-services.xml (added)
+++ cxf/dosgi/trunk/dsw/cxf-dsw/src/test/resources/OSGI-INF/remote-service/alt-remote-services.xml Tue Feb 24 09:38:22 2009
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+-->
+
+<service-descriptions xmlns="http://www.osgi.org/xmlns/sd/v1.0.0">
+ <service-description>
+ <provide interface="org.apache.cxf.dosgi.dsw.hooks.TestService" />
+ <provide interface="org.apache.cxf.dosgi.dsw.hooks.CxfPublishHookTest$AdditionalInterface" />
+
+ <property name="osgi.remote.interfaces" value="*" />
+ <property name="osgi.remote.requires.intents" value="SOAP HTTP" />
+ <property name="osgi.remote.configuration.type" value="pojo" />
+ <property name="osgi.remote.configuration.pojo.address" value="http://localhost:9000/hello" />
+ </service-description>
+</service-descriptions>
Propchange: cxf/dosgi/trunk/dsw/cxf-dsw/src/test/resources/OSGI-INF/remote-service/alt-remote-services.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/dosgi/trunk/dsw/cxf-dsw/src/test/resources/OSGI-INF/remote-service/alt-remote-services.xml
------------------------------------------------------------------------------
svn:keywords = Rev Date
Propchange: cxf/dosgi/trunk/dsw/cxf-dsw/src/test/resources/OSGI-INF/remote-service/alt-remote-services.xml
------------------------------------------------------------------------------
svn:mime-type = text/xml
Modified: cxf/dosgi/trunk/samples/greeter/client/src/main/resources/OSGI-INF/remote-service/remote-services.xml
URL: http://svn.apache.org/viewvc/cxf/dosgi/trunk/samples/greeter/client/src/main/resources/OSGI-INF/remote-service/remote-services.xml?rev=747315&r1=747314&r2=747315&view=diff
==============================================================================
--- cxf/dosgi/trunk/samples/greeter/client/src/main/resources/OSGI-INF/remote-service/remote-services.xml (original)
+++ cxf/dosgi/trunk/samples/greeter/client/src/main/resources/OSGI-INF/remote-service/remote-services.xml Tue Feb 24 09:38:22 2009
@@ -16,8 +16,8 @@
<service-descriptions xmlns="http://www.osgi.org/xmlns/sd/v1.0.0">
<service-description>
<provide interface="org.apache.cxf.dosgi.samples.greeter.GreeterService" />
- <property name="osgi.remote.interfaces">*</property>
- <property name="osgi.remote.configuration.type">pojo</property>
- <property name="osgi.remote.configuration.pojo.address">http://localhost:9090/greeter</property>
+ <property name="osgi.remote.interfaces" value="*" />
+ <property name="osgi.remote.configuration.type" value="pojo" />
+ <property name="osgi.remote.configuration.pojo.address" value="http://localhost:9090/greeter" />
</service-description>
</service-descriptions>
Modified: cxf/dosgi/trunk/systests/multi_bundle_distro/src/test/resources/OSGI-INF/remote-service/remote-services.xml
URL: http://svn.apache.org/viewvc/cxf/dosgi/trunk/systests/multi_bundle_distro/src/test/resources/OSGI-INF/remote-service/remote-services.xml?rev=747315&r1=747314&r2=747315&view=diff
==============================================================================
--- cxf/dosgi/trunk/systests/multi_bundle_distro/src/test/resources/OSGI-INF/remote-service/remote-services.xml (original)
+++ cxf/dosgi/trunk/systests/multi_bundle_distro/src/test/resources/OSGI-INF/remote-service/remote-services.xml Tue Feb 24 09:38:22 2009
@@ -16,9 +16,9 @@
<service-descriptions xmlns="http://www.osgi.org/xmlns/sd/v1.0.0">
<service-description>
<provide interface="org.apache.cxf.dosgi.samples.greeter.GreeterService" />
- <property name="osgi.remote.interfaces">*</property>
- <property name="osgi.remote.requires.intents">SOAP HTTP</property>
- <property name="osgi.remote.configuration.type">pojo</property>
- <property name="osgi.remote.configuration.pojo.address">http://localhost:9090/greeter</property>
+ <property name="osgi.remote.interfaces" value="*" />
+ <property name="osgi.remote.requires.intents" value="SOAP HTTP" />
+ <property name="osgi.remote.configuration.type" value="pojo" />
+ <property name="osgi.remote.configuration.pojo.address" value="http://localhost:9090/greeter" />
</service-description>
</service-descriptions>