You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ace.apache.org by ma...@apache.org on 2013/04/03 15:35:22 UTC

svn commit: r1464005 - in /ace/trunk: org.apache.ace.discovery.api/ org.apache.ace.discovery.property/ org.apache.ace.discovery.upnp/ org.apache.ace.discovery/ org.apache.ace.discovery/.settings/ org.apache.ace.discovery/src/ org.apache.ace.discovery/s...

Author: marrs
Date: Wed Apr  3 13:35:21 2013
New Revision: 1464005

URL: http://svn.apache.org/r1464005
Log:
ACE-333 Merged o.a.a.discovery.

Added:
    ace/trunk/org.apache.ace.discovery/
    ace/trunk/org.apache.ace.discovery/.classpath
    ace/trunk/org.apache.ace.discovery/.project
    ace/trunk/org.apache.ace.discovery/.settings/
    ace/trunk/org.apache.ace.discovery/.settings/org.eclipse.jdt.core.prefs
    ace/trunk/org.apache.ace.discovery/api.bnd
    ace/trunk/org.apache.ace.discovery/bnd.bnd
    ace/trunk/org.apache.ace.discovery/build.xml
    ace/trunk/org.apache.ace.discovery/property.bnd
    ace/trunk/org.apache.ace.discovery/src/
    ace/trunk/org.apache.ace.discovery/src/org/
    ace/trunk/org.apache.ace.discovery/src/org/apache/
    ace/trunk/org.apache.ace.discovery/src/org/apache/ace/
    ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/
    ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/Discovery.java
    ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/packageinfo
    ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/property/
    ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/property/Activator.java
    ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/property/PropertyBasedDiscovery.java
    ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/property/constants/
    ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/property/constants/DiscoveryConstants.java
    ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/upnp/
    ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/upnp/Activator.java
    ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/upnp/UPnPBasedDiscovery.java
    ace/trunk/org.apache.ace.discovery/test/
    ace/trunk/org.apache.ace.discovery/test/org/
    ace/trunk/org.apache.ace.discovery/test/org/apache/
    ace/trunk/org.apache.ace.discovery/test/org/apache/ace/
    ace/trunk/org.apache.ace.discovery/test/org/apache/ace/discovery/
    ace/trunk/org.apache.ace.discovery/test/org/apache/ace/discovery/property/
    ace/trunk/org.apache.ace.discovery/test/org/apache/ace/discovery/property/PropertyBasedDiscoveryTest.java
    ace/trunk/org.apache.ace.discovery/test/org/apache/ace/discovery/property/SimpleDiscoveryTest.java
    ace/trunk/org.apache.ace.discovery/test/org/apache/ace/discovery/upnp/
    ace/trunk/org.apache.ace.discovery/test/org/apache/ace/discovery/upnp/SimpleDiscoveryTest.java
    ace/trunk/org.apache.ace.discovery/upnp.bnd
Removed:
    ace/trunk/org.apache.ace.discovery.api/
    ace/trunk/org.apache.ace.discovery.property/
    ace/trunk/org.apache.ace.discovery.upnp/

Added: ace/trunk/org.apache.ace.discovery/.classpath
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.discovery/.classpath?rev=1464005&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.discovery/.classpath (added)
+++ ace/trunk/org.apache.ace.discovery/.classpath Wed Apr  3 13:35:21 2013
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" output="bin_test" path="test"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+	<classpathentry kind="con" path="aQute.bnd.classpath.container"/>
+	<classpathentry kind="con" path="org.testng.TESTNG_CONTAINER"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>

Added: ace/trunk/org.apache.ace.discovery/.project
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.discovery/.project?rev=1464005&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.discovery/.project (added)
+++ ace/trunk/org.apache.ace.discovery/.project Wed Apr  3 13:35:21 2013
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.apache.ace.discovery</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>bndtools.core.bndbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>bndtools.core.bndnature</nature>
+	</natures>
+</projectDescription>

Added: ace/trunk/org.apache.ace.discovery/.settings/org.eclipse.jdt.core.prefs
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.discovery/.settings/org.eclipse.jdt.core.prefs?rev=1464005&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.discovery/.settings/org.eclipse.jdt.core.prefs (added)
+++ ace/trunk/org.apache.ace.discovery/.settings/org.eclipse.jdt.core.prefs Wed Apr  3 13:35:21 2013
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6

Added: ace/trunk/org.apache.ace.discovery/api.bnd
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.discovery/api.bnd?rev=1464005&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.discovery/api.bnd (added)
+++ ace/trunk/org.apache.ace.discovery/api.bnd Wed Apr  3 13:35:21 2013
@@ -0,0 +1,2 @@
+Export-Package: org.apache.ace.discovery
+Bundle-Version: 1.0.0

Added: ace/trunk/org.apache.ace.discovery/bnd.bnd
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.discovery/bnd.bnd?rev=1464005&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.discovery/bnd.bnd (added)
+++ ace/trunk/org.apache.ace.discovery/bnd.bnd Wed Apr  3 13:35:21 2013
@@ -0,0 +1,6 @@
+-buildpath: osgi.core,\
+	osgi.cmpn,\
+	org.apache.felix.dependencymanager,\
+	org.apache.ace.test;version=latest,\
+	org.easymock
+-sub: *.bnd
\ No newline at end of file

Added: ace/trunk/org.apache.ace.discovery/build.xml
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.discovery/build.xml?rev=1464005&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.discovery/build.xml (added)
+++ ace/trunk/org.apache.ace.discovery/build.xml Wed Apr  3 13:35:21 2013
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="project" default="build">
+
+	<!-- -->
+
+	<import file="../cnf/build.xml" />
+</project>

Added: ace/trunk/org.apache.ace.discovery/property.bnd
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.discovery/property.bnd?rev=1464005&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.discovery/property.bnd (added)
+++ ace/trunk/org.apache.ace.discovery/property.bnd Wed Apr  3 13:35:21 2013
@@ -0,0 +1,4 @@
+Private-Package: org.apache.ace.discovery.property,\
+	org.apache.ace.discovery.property.constants
+Bundle-Activator: org.apache.ace.discovery.property.Activator
+Bundle-Version: 1.0.0

Added: ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/Discovery.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/Discovery.java?rev=1464005&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/Discovery.java (added)
+++ ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/Discovery.java Wed Apr  3 13:35:21 2013
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+package org.apache.ace.discovery;
+
+import java.net.URL;
+
+/**
+ * Service interface that can be used to locate the server.
+ */
+public interface Discovery
+{
+
+    /**
+     * Discovers the location of the server.
+     *
+     * @return URL pointing to the base address of the server
+     */
+    public URL discover();
+
+}
\ No newline at end of file

Added: ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/packageinfo
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/packageinfo?rev=1464005&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/packageinfo (added)
+++ ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/packageinfo Wed Apr  3 13:35:21 2013
@@ -0,0 +1 @@
+version 1.0
\ No newline at end of file

Added: ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/property/Activator.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/property/Activator.java?rev=1464005&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/property/Activator.java (added)
+++ ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/property/Activator.java Wed Apr  3 13:35:21 2013
@@ -0,0 +1,129 @@
+/*
+ * 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.
+ */
+package org.apache.ace.discovery.property;
+
+import java.net.MalformedURLException;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.ace.discovery.Discovery;
+import org.apache.ace.discovery.property.constants.DiscoveryConstants;
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyActivatorBase;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedServiceFactory;
+import org.osgi.service.log.LogService;
+
+public class Activator extends DependencyActivatorBase implements ManagedServiceFactory {
+    private static final String MA_NAME = "ma";
+    private DependencyManager m_manager;
+    private BundleContext m_context;
+    private final Map /*<String, Component>*/ m_instances = new HashMap();
+    private volatile LogService m_log;
+
+    public void init(BundleContext context, DependencyManager manager) throws Exception {
+        Dictionary properties = new Hashtable();
+        properties.put(Constants.SERVICE_PID, DiscoveryConstants.DISCOVERY_PID);
+        manager.add(createComponent()
+            .setInterface(new String[] {Discovery.class.getName()}, properties)
+            .setImplementation(PropertyBasedDiscovery.class)
+            .add(createConfigurationDependency()
+                .setPid(DiscoveryConstants.DISCOVERY_PID))
+            .add(createServiceDependency()
+                .setService(LogService.class)
+                .setRequired(false)));
+        manager.add(createComponent()
+            .setInterface(ManagedServiceFactory.class.getName(), new Properties() {{ put(Constants.SERVICE_PID, DiscoveryConstants.DISCOVERY_FACTORY_PID); }})
+            .setImplementation(this)
+            .add(createServiceDependency()
+                .setService(LogService.class)
+                .setRequired(false))
+            );
+    }
+
+    public void destroy(BundleContext context, DependencyManager manager) throws Exception {
+        // do nothing
+    }
+    
+    public String getName() {
+        return "Discovery Service Factory";
+    }
+
+    public void updated(String pid, Dictionary dict) throws ConfigurationException {
+        String ma = (String) dict.get(MA_NAME);
+        String id = (String) dict.get(DiscoveryConstants.DISCOVERY_URL_KEY);
+        
+        if (id == null) {
+            throw new ConfigurationException(DiscoveryConstants.DISCOVERY_URL_KEY, "Must be specified");
+        }
+
+        boolean needToAddComponent = false;
+        Component component;
+        synchronized (m_instances) {
+            component = (Component) m_instances.get(pid);
+            if (component == null) {
+                Properties props = new Properties();
+                if ((ma != null) && (ma.length() > 0)) {
+                    props.put(MA_NAME, ma);
+                }
+                props.put(DiscoveryConstants.DISCOVERY_URL_KEY, id);
+                component = m_manager.createComponent()
+                    .setInterface(Discovery.class.getName(), props)
+                    .setImplementation(new PropertyBasedDiscovery(id))
+                    .add(createServiceDependency()
+                        .setService(LogService.class)
+                        .setRequired(false)
+                    );
+                m_instances.put(pid, component);
+                needToAddComponent = true;
+            }
+        }
+        if (needToAddComponent) {
+            m_manager.add(component);
+        }
+        else {
+            Object service = component.getService();
+            if (service instanceof PropertyBasedDiscovery) {
+                PropertyBasedDiscovery identification = (PropertyBasedDiscovery) service;
+                try {
+                    identification.setURL(id);
+                }
+                catch (MalformedURLException e) {
+                    throw new ConfigurationException(DiscoveryConstants.DISCOVERY_URL_KEY, "Malformed URL", e);
+                }
+            }
+        }
+    }
+
+    public void deleted(String pid) {
+        Component log;
+        synchronized (m_instances) {
+            log = (Component) m_instances.remove(pid);
+        }
+        if (log != null) {
+            m_manager.remove(log);
+        }
+    }
+}
\ No newline at end of file

Added: ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/property/PropertyBasedDiscovery.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/property/PropertyBasedDiscovery.java?rev=1464005&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/property/PropertyBasedDiscovery.java (added)
+++ ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/property/PropertyBasedDiscovery.java Wed Apr  3 13:35:21 2013
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+package org.apache.ace.discovery.property;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Dictionary;
+
+import org.apache.ace.discovery.Discovery;
+import org.apache.ace.discovery.property.constants.DiscoveryConstants;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedService;
+import org.osgi.service.log.LogService;
+
+/**
+ * Simple implementation of the <code>Discovery</code> interface. It 'discovers'
+ * the Provisioning Server by implementing the <code>ManagedService</code> and having the
+ * location configured by <code>ConfigurationAdmin</code>. If no configuration or a <code>null</code>
+ * configuration has been supplied by <code>ConfigurationAdmin</code> the location stored
+ * in <code>TargetConstants.DISCOVERY_DEFAULT_URL</code> will be used.
+ */
+public class PropertyBasedDiscovery implements Discovery, ManagedService {
+    private final Object LOCK = new Object();
+    public volatile LogService m_log; /* will be injected by dependencymanager */
+    private URL m_serverURL; /* managed by configadmin */
+
+    public PropertyBasedDiscovery() {
+    }
+    
+    public PropertyBasedDiscovery(String url) {
+        try {
+            setURL(url);
+        }
+        catch (MalformedURLException e) {
+            throw new IllegalArgumentException("Cannot create instance, invalid URL argument", e);
+        }
+    }
+    
+    public URL getURL() {
+        synchronized (LOCK) {
+            return m_serverURL;
+        }
+    }
+    
+    public void setURL(String id) throws MalformedURLException {
+        setURL(new URL(id));
+    }
+    
+    public void setURL(URL id) {
+        synchronized (LOCK) {
+            m_serverURL = id;
+        }
+    }
+    
+
+    public synchronized void updated(Dictionary dictionary) throws ConfigurationException {
+        try {
+            if(dictionary != null) {
+                setURL(new URL((String) dictionary.get(DiscoveryConstants.DISCOVERY_URL_KEY)));
+            }
+        }
+        catch (MalformedURLException e) {
+            throw new ConfigurationException(DiscoveryConstants.DISCOVERY_URL_KEY, "Malformed URL", e);
+        }
+    }
+
+    public synchronized URL discover() {
+        return getURL();
+    }
+}
\ No newline at end of file

Added: ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/property/constants/DiscoveryConstants.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/property/constants/DiscoveryConstants.java?rev=1464005&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/property/constants/DiscoveryConstants.java (added)
+++ ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/property/constants/DiscoveryConstants.java Wed Apr  3 13:35:21 2013
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+package org.apache.ace.discovery.property.constants;
+
+public interface DiscoveryConstants {
+    public static final String DISCOVERY_PID = "org.apache.ace.discovery.property";
+    public static final String DISCOVERY_FACTORY_PID = "org.apache.ace.discovery.property.factory";
+    public static final String DISCOVERY_URL_KEY = "serverURL";
+}
\ No newline at end of file

Added: ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/upnp/Activator.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/upnp/Activator.java?rev=1464005&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/upnp/Activator.java (added)
+++ ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/upnp/Activator.java Wed Apr  3 13:35:21 2013
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+package org.apache.ace.discovery.upnp;
+
+import org.apache.ace.discovery.Discovery;
+import org.apache.felix.dm.DependencyActivatorBase;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.log.LogService;
+import org.osgi.service.upnp.UPnPDevice;
+
+public class Activator extends DependencyActivatorBase {
+
+    public void init(BundleContext context, DependencyManager manager) throws Exception {
+        StringBuffer deviceFilter = new StringBuffer();
+        deviceFilter.append("(")
+            .append(UPnPDevice.TYPE).append("=")
+            .append(UPnPBasedDiscovery.DEVICE_TYPE).append(")");
+
+        manager.add(createComponent()
+            .setInterface(new String[] {Discovery.class.getName()}, null)
+            .setImplementation(UPnPBasedDiscovery.class)
+                .add(createServiceDependency()
+                    .setService(LogService.class)
+                    .setRequired(false))
+                //not required
+                .add(createServiceDependency()
+                    .setService(UPnPDevice.class, deviceFilter.toString())
+                    .setCallbacks("added", "removed")
+                    .setRequired(false))
+                    );
+    }
+
+    public void destroy(BundleContext context, DependencyManager manager) throws Exception {
+        // do nothing
+    }
+}
\ No newline at end of file

Added: ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/upnp/UPnPBasedDiscovery.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/upnp/UPnPBasedDiscovery.java?rev=1464005&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/upnp/UPnPBasedDiscovery.java (added)
+++ ace/trunk/org.apache.ace.discovery/src/org/apache/ace/discovery/upnp/UPnPBasedDiscovery.java Wed Apr  3 13:35:21 2013
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+package org.apache.ace.discovery.upnp;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.List;
+
+import org.apache.ace.discovery.Discovery;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogService;
+import org.osgi.service.upnp.UPnPAction;
+import org.osgi.service.upnp.UPnPDevice;
+import org.osgi.service.upnp.UPnPService;
+
+/**
+ * Simple implementation of the <code>Discovery</code> interface. It 'discovers'
+ * the server by means of UPnP.
+ */
+public class UPnPBasedDiscovery implements Discovery {
+    final static String DEVICE_TYPE = "urn:schemas-upnp-org:device:ProvisioningDevice:1";
+    final static String SERVICE_ID = "urn:upnp-org:serviceId:LocationService:1";
+    final static String ACTION_GET_LOCATION = "GetLocation";
+    final static String ACTION_GET_TYPE = "GetServerType";
+    final static String ACTION_GET_LOAD = "GetServerLoad";
+
+    public volatile LogService m_log; /* will be injected by dependencymanager */
+    private List m_devices;
+
+    public void start() {
+        m_devices = new ArrayList();
+    }
+
+    public void added(ServiceReference ref, Object device) {
+        if (device instanceof UPnPDevice) {
+            m_devices.add(device);
+        }
+    }
+
+    public void removed(Object device) {
+        m_devices.remove(device);
+    }
+
+    public synchronized URL discover() {
+        try {
+            return getLocation();
+        }
+        catch (Exception e) {
+            m_log.log(LogService.LOG_DEBUG, "unable to retrieve location property", e);
+        }
+
+        return null;
+    }
+
+    private URL getLocation() {
+        UPnPAction action = getAction(ACTION_GET_LOCATION);
+        try {
+            Dictionary dict = action.invoke(null);
+            String location = (String)dict.get(action.getOutputArgumentNames()[0]);
+            return new URL(location);
+        }
+        catch (Exception e) {}
+        return null;
+    }
+
+    private String getType() {
+        UPnPAction action = getAction(ACTION_GET_TYPE);
+        try {
+            Dictionary dict = action.invoke(null);
+            return (String)dict.get(action.getOutputArgumentNames()[0]);
+        }
+        catch (Exception e) {}
+        return "Unknown";
+    }
+
+    private int getLoad() {
+        UPnPAction action = getAction(ACTION_GET_LOAD);
+        try {
+            Dictionary dict = action.invoke(null);
+            Integer val = (Integer)dict.get(action.getOutputArgumentNames()[0]);
+            return val.intValue();
+        }
+        catch (Exception e) {
+            //ignore, just report worst case
+        }
+        return 100;
+    }
+
+    private UPnPAction getAction(String name) {
+        UPnPDevice device = null;
+
+        //zero-order implementation
+        if ( m_devices.size() > 0 ) {
+            device = (UPnPDevice)m_devices.iterator().next();
+        }
+
+        if (device != null) {
+                UPnPService svc = device.getService(SERVICE_ID);
+                if (svc != null) {
+                    return svc.getAction(name);
+                }
+        }
+        return null;
+    }
+}
\ No newline at end of file

Added: ace/trunk/org.apache.ace.discovery/test/org/apache/ace/discovery/property/PropertyBasedDiscoveryTest.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.discovery/test/org/apache/ace/discovery/property/PropertyBasedDiscoveryTest.java?rev=1464005&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.discovery/test/org/apache/ace/discovery/property/PropertyBasedDiscoveryTest.java (added)
+++ ace/trunk/org.apache.ace.discovery/test/org/apache/ace/discovery/property/PropertyBasedDiscoveryTest.java Wed Apr  3 13:35:21 2013
@@ -0,0 +1,48 @@
+/*
+ * 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.apache.ace.discovery.property;
+
+import static org.apache.ace.test.utils.TestUtils.UNIT;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.apache.ace.discovery.property.constants.DiscoveryConstants;
+import org.osgi.service.cm.ConfigurationException;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class PropertyBasedDiscoveryTest {
+    @Test(groups = { UNIT })
+    public void discoverWithoutPropertyUpdate() {
+        PropertyBasedDiscovery discovery = new PropertyBasedDiscovery();
+        URL url = discovery.discover();
+        Assert.assertNull(url);
+    }
+
+    @Test(groups = { UNIT })
+    public void discoverWithPropertyUpdate() throws ConfigurationException, URISyntaxException {
+        PropertyBasedDiscovery discovery = new PropertyBasedDiscovery();
+        Dictionary dict = new Hashtable();
+        dict.put(DiscoveryConstants.DISCOVERY_URL_KEY, "file://local");
+        discovery.updated(dict);
+        URL url = discovery.discover();
+        Assert.assertEquals(url.toURI(), new URI("file://local"));
+    }
+}

Added: ace/trunk/org.apache.ace.discovery/test/org/apache/ace/discovery/property/SimpleDiscoveryTest.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.discovery/test/org/apache/ace/discovery/property/SimpleDiscoveryTest.java?rev=1464005&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.discovery/test/org/apache/ace/discovery/property/SimpleDiscoveryTest.java (added)
+++ ace/trunk/org.apache.ace.discovery/test/org/apache/ace/discovery/property/SimpleDiscoveryTest.java Wed Apr  3 13:35:21 2013
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+package org.apache.ace.discovery.property;
+
+import static org.apache.ace.test.utils.TestUtils.UNIT;
+
+import java.net.URL;
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.apache.ace.discovery.property.constants.DiscoveryConstants;
+import org.apache.ace.test.constants.TestConstants;
+import org.osgi.service.cm.ConfigurationException;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+public class SimpleDiscoveryTest {
+
+    private static final String SERVERURL_KEY = DiscoveryConstants.DISCOVERY_URL_KEY;
+    private static final String VALID_URL = "http://test.url.com:" + TestConstants.PORT;
+    private static final String INVALID_URL = "malformed url";
+
+    private PropertyBasedDiscovery m_discovery;
+
+    @BeforeTest(alwaysRun = true)
+    protected void setUp() throws Exception {
+        m_discovery = new PropertyBasedDiscovery();
+    }
+
+    /**
+     * Test if setting a valid configuration is handled correctly
+     * @throws Exception
+     */
+    @Test(groups = { UNIT })
+    public void simpleDiscoveryValidConfiguration() throws ConfigurationException {
+        Dictionary<String, String> properties = new Hashtable<String, String>();
+        properties.put(SERVERURL_KEY, VALID_URL);
+        m_discovery.updated(properties);
+        URL url = m_discovery.discover();
+        assert VALID_URL.equals(url.toString()) : "Configured url was not returned";
+    }
+
+    /**
+     * Test if setting an invalid configuration is handled correctly.
+     * @throws ConfigurationException
+     */
+    @Test(groups = {UNIT}, expectedExceptions = ConfigurationException.class)
+    public void simpleDiscoveryInvalidConfiguration() throws ConfigurationException {
+        Dictionary<String, String> properties = new Hashtable<String, String>();
+        properties.put(SERVERURL_KEY, INVALID_URL);
+        m_discovery.updated(properties);
+    }
+
+    /**
+     * Test if supplying an empty configuration results in the service's default being used.
+     * @throws ConfigurationException
+     */
+    @Test(groups = {UNIT})
+    public void simpleDiscoveryEmptyConfiguration() throws ConfigurationException {
+        // set valid config
+        Dictionary<String, String> properties = new Hashtable<String, String>();
+        properties.put(SERVERURL_KEY, VALID_URL);
+        m_discovery.updated(properties);
+        // set empty config
+        m_discovery.updated(null);
+    }
+}

Added: ace/trunk/org.apache.ace.discovery/test/org/apache/ace/discovery/upnp/SimpleDiscoveryTest.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.discovery/test/org/apache/ace/discovery/upnp/SimpleDiscoveryTest.java?rev=1464005&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.discovery/test/org/apache/ace/discovery/upnp/SimpleDiscoveryTest.java (added)
+++ ace/trunk/org.apache.ace.discovery/test/org/apache/ace/discovery/upnp/SimpleDiscoveryTest.java Wed Apr  3 13:35:21 2013
@@ -0,0 +1,139 @@
+/*
+ * 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.
+ */
+package org.apache.ace.discovery.upnp;
+
+import static org.apache.ace.test.utils.TestUtils.UNIT;
+
+import java.net.URL;
+import java.util.Properties;
+
+import org.apache.ace.test.constants.TestConstants;
+import org.easymock.EasyMock;
+import org.easymock.IMocksControl;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.upnp.UPnPAction;
+import org.osgi.service.upnp.UPnPDevice;
+import org.osgi.service.upnp.UPnPService;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class SimpleDiscoveryTest {
+
+    private static final String VALID_URL = "http://test.url.com:" + TestConstants.PORT;
+    private static final String INVALID_URL = "malformed url";
+
+    private UPnPBasedDiscovery m_discovery;
+
+
+    private IMocksControl m_control = EasyMock.createControl();
+
+
+    @BeforeMethod(alwaysRun = true)
+    protected void setUp() throws Exception {
+        m_discovery = new UPnPBasedDiscovery();
+        m_discovery.start();
+    }
+
+    /**
+     * Test if discovering while there's no UPnPService
+     * works as expected (returns null)
+     *
+     * @throws Exception
+     */
+    @Test(groups = { UNIT })
+    public void simpleDiscoveryNoUPnPServices() throws ConfigurationException {
+        URL url = m_discovery.discover();
+        assert (url == null) : "Invalid url was returned (should have been null): " + url;
+    }
+
+    private UPnPDevice expectDeviceAdditionForURL(String url, String type) throws Exception {
+        final String returnLocation = "returnLocation";
+        final String returnType = "returnType";
+
+        final Properties p = new Properties();
+        p.put(returnLocation, url);
+        p.put(returnType, type);
+
+        m_control.checkOrder(false);
+
+        final UPnPAction action1 = m_control.createMock(UPnPAction.class);
+        EasyMock.expect(action1.getOutputArgumentNames()).andReturn(new String[]{returnLocation}).anyTimes();
+        EasyMock.expect(action1.invoke(null)).andReturn(p).anyTimes();
+
+        final UPnPAction action2 = m_control.createMock(UPnPAction.class);
+        EasyMock.expect(action2.getOutputArgumentNames()).andReturn(new String[]{returnType}).anyTimes();
+        EasyMock.expect(action2.invoke(null)).andReturn(p).anyTimes();
+
+        final UPnPService service = m_control.createMock(UPnPService.class);
+        EasyMock.expect(service.getAction("GetLocation")).andReturn(action1).anyTimes();
+        EasyMock.expect(service.getAction("GetServerType")).andReturn(action2).anyTimes();
+
+        UPnPDevice device = m_control.createMock(UPnPDevice.class);
+        EasyMock.expect(device.getService(EasyMock.isA(String.class))).andReturn(service).anyTimes();
+
+        return device;
+    }
+
+    /**
+     * Test if the url as provided by a UPnPDevice
+     * is returned as expected.
+     * @throws Exception
+     */
+    @Test(groups = {UNIT})
+    public void simpleDiscoverySingleUPnPDevice() throws Exception {
+
+        m_control.reset();
+
+        UPnPDevice device = expectDeviceAdditionForURL(VALID_URL, "RelayServer");
+        ServiceReference ref = m_control.createMock(ServiceReference.class);
+
+        m_control.replay();
+
+        m_discovery.added(ref, device);
+        m_discovery.discover();
+
+        m_control.verify();
+    }
+
+    /**
+     * Test if the url as provided by a UPnPDevice
+     * is returned as expected.
+     * @throws Exception
+     */
+    @Test(groups = {UNIT})
+    public void simpleDiscoveryMultipleUPnPDevices() throws Exception {
+        m_control.reset();
+
+        UPnPDevice device1 = expectDeviceAdditionForURL(VALID_URL, "RelayServer");
+        UPnPDevice device2 = expectDeviceAdditionForURL(INVALID_URL, "RelayServer");
+
+        ServiceReference ref = m_control.createMock(ServiceReference.class);
+
+        m_control.replay();
+
+        m_discovery.added(ref, device1);
+        m_discovery.added(ref, device2);
+
+        URL url = m_discovery.discover();
+        assert VALID_URL.equals(url.toString()) : "Valid url was not returned";
+
+        m_control.verify();
+    }
+}

Added: ace/trunk/org.apache.ace.discovery/upnp.bnd
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.discovery/upnp.bnd?rev=1464005&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.discovery/upnp.bnd (added)
+++ ace/trunk/org.apache.ace.discovery/upnp.bnd Wed Apr  3 13:35:21 2013
@@ -0,0 +1,3 @@
+Private-Package: org.apache.ace.discovery.upnp
+Bundle-Activator: org.apache.ace.discovery.upnp.Activator
+Bundle-Version: 1.0.0