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>