Author: pderop
Date: Mon Jan 18 23:07:15 2016
New Revision: 1725381

URL: http://svn.apache.org/viewvc?rev=1725381&view=rev
Log:
Added tests.

Added:
    
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceDependencyInjectionTest.java
    
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceDependencyPropagateTest.java
    
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/TemporalServiceDependencyTest.java
Modified:
    felix/sandbox/pderop/dependencymanager-lambda/TODO
    
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AspectWithPropagationTest.java
    
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/CompositionTest.java
    
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/FactoryInjectedWithConfigurationBeforeTheCreateMethod.java
    
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/MultipleExtraDependencyTest2.java
    
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/MultipleServiceDependencyTest.java
    
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/RemovedDependencyTest.java
    
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceDependencyCallbackSignaturesTest.java
    
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/ServiceDependencyBuilder.java
    
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ServiceDependencyBuilderImpl.java

Modified: felix/sandbox/pderop/dependencymanager-lambda/TODO
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/TODO?rev=1725381&r1=1725380&r2=1725381&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/TODO (original)
+++ felix/sandbox/pderop/dependencymanager-lambda/TODO Mon Jan 18 23:07:15 2016
@@ -1,5 +1,3 @@
-- Finish to adapt all DependencyManager integration tests
-
 - add BundeAdapter
 
 - Javadocs

Modified: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AspectWithPropagationTest.java
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AspectWithPropagationTest.java?rev=1725381&r1=1725380&r2=1725381&view=diff
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AspectWithPropagationTest.java
 (original)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AspectWithPropagationTest.java
 Mon Jan 18 23:07:15 2016
@@ -17,7 +17,8 @@
  * under the License.
  */
 package org.apache.felix.dm.builder.lambda.itest;
-import static org.apache.felix.dm.builder.lambda.DependencyActivatorBase.*;
+import static 
org.apache.felix.dm.builder.lambda.DependencyActivatorBase.adapter;
+import static 
org.apache.felix.dm.builder.lambda.DependencyActivatorBase.aspect;
 import static 
org.apache.felix.dm.builder.lambda.DependencyActivatorBase.component;
 
 import java.util.Dictionary;

Modified: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/CompositionTest.java
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/CompositionTest.java?rev=1725381&r1=1725380&r2=1725381&view=diff
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/CompositionTest.java
 (original)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/CompositionTest.java
 Mon Jan 18 23:07:15 2016
@@ -18,9 +18,10 @@
  */
 package org.apache.felix.dm.builder.lambda.itest;
 
+import static 
org.apache.felix.dm.builder.lambda.DependencyActivatorBase.component;
+
 import org.apache.felix.dm.Component;
 import org.apache.felix.dm.DependencyManager;
-import static org.apache.felix.dm.builder.lambda.DependencyActivatorBase.*;
 
 
 /**

Modified: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/FactoryInjectedWithConfigurationBeforeTheCreateMethod.java
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/FactoryInjectedWithConfigurationBeforeTheCreateMethod.java?rev=1725381&r1=1725380&r2=1725381&view=diff
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/FactoryInjectedWithConfigurationBeforeTheCreateMethod.java
 (original)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/FactoryInjectedWithConfigurationBeforeTheCreateMethod.java
 Mon Jan 18 23:07:15 2016
@@ -18,18 +18,17 @@
  */
 package org.apache.felix.dm.builder.lambda.itest;
 
+import static 
org.apache.felix.dm.builder.lambda.DependencyActivatorBase.component;
+
 import java.io.IOException;
 import java.util.Dictionary;
 import java.util.Hashtable;
-import java.util.Properties;
 
 import org.apache.felix.dm.Component;
 import org.apache.felix.dm.DependencyManager;
 import org.junit.Assert;
 import org.osgi.service.cm.Configuration;
 import org.osgi.service.cm.ConfigurationAdmin;
-import static org.apache.felix.dm.builder.lambda.DependencyActivatorBase.*;
-import static org.apache.felix.dm.builder.lambda.Cb.*;
 
 
 /**

Modified: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/MultipleExtraDependencyTest2.java
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/MultipleExtraDependencyTest2.java?rev=1725381&r1=1725380&r2=1725381&view=diff
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/MultipleExtraDependencyTest2.java
 (original)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/MultipleExtraDependencyTest2.java
 Mon Jan 18 23:07:15 2016
@@ -18,13 +18,12 @@
  */
 package org.apache.felix.dm.builder.lambda.itest;
 
-import java.util.Hashtable;
+import static 
org.apache.felix.dm.builder.lambda.DependencyActivatorBase.component;
 
 import org.apache.felix.dm.Component;
 import org.apache.felix.dm.Dependency;
 import org.apache.felix.dm.DependencyManager;
 import org.apache.felix.dm.ServiceDependency;
-import static org.apache.felix.dm.builder.lambda.DependencyActivatorBase.*;
 
 /**
  * Tests for extra dependencies which are declared from service's init method.

Modified: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/MultipleServiceDependencyTest.java
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/MultipleServiceDependencyTest.java?rev=1725381&r1=1725380&r2=1725381&view=diff
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/MultipleServiceDependencyTest.java
 (original)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/MultipleServiceDependencyTest.java
 Mon Jan 18 23:07:15 2016
@@ -18,12 +18,11 @@
  */
 package org.apache.felix.dm.builder.lambda.itest;
 
-import java.util.Hashtable;
+import static 
org.apache.felix.dm.builder.lambda.DependencyActivatorBase.component;
 
 import org.apache.felix.dm.Component;
 import org.apache.felix.dm.DependencyManager;
 import org.osgi.framework.Constants;
-import static org.apache.felix.dm.builder.lambda.DependencyActivatorBase.*;
 
 /**
  * @author <a href="mailto:[email protected]";>Felix Project Team</a>

Modified: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/RemovedDependencyTest.java
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/RemovedDependencyTest.java?rev=1725381&r1=1725380&r2=1725381&view=diff
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/RemovedDependencyTest.java
 (original)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/RemovedDependencyTest.java
 Mon Jan 18 23:07:15 2016
@@ -18,22 +18,20 @@
  */
 package org.apache.felix.dm.builder.lambda.itest;
 
+import static 
org.apache.felix.dm.builder.lambda.DependencyActivatorBase.component;
+import static 
org.apache.felix.dm.builder.lambda.DependencyActivatorBase.serviceDependency;
+
 import java.util.ArrayList;
 import java.util.Hashtable;
 import java.util.List;
 import java.util.Properties;
 
-import org.junit.Assert;
-
 import org.apache.felix.dm.Component;
 import org.apache.felix.dm.Dependency;
 import org.apache.felix.dm.DependencyManager;
-import org.apache.felix.dm.builder.lambda.ComponentBuilder;
-import org.apache.felix.dm.builder.lambda.DependencyBuilder;
+import org.junit.Assert;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
-import static org.apache.felix.dm.builder.lambda.DependencyActivatorBase.*;
-import static org.apache.felix.dm.builder.lambda.Cb.*;
 
 /**
  * One consumer, Three providers. The Consumer has two required dependency on 
provider1, provider2, and one 

Modified: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceDependencyCallbackSignaturesTest.java
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceDependencyCallbackSignaturesTest.java?rev=1725381&r1=1725380&r2=1725381&view=diff
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceDependencyCallbackSignaturesTest.java
 (original)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceDependencyCallbackSignaturesTest.java
 Mon Jan 18 23:07:15 2016
@@ -18,8 +18,9 @@
  */
 package org.apache.felix.dm.builder.lambda.itest;
 
-import static org.apache.felix.dm.builder.lambda.Cb.*;
+import static org.apache.felix.dm.builder.lambda.Cb.ADD;
 import static org.apache.felix.dm.builder.lambda.Cb.CHG;
+import static org.apache.felix.dm.builder.lambda.Cb.REM;
 import static 
org.apache.felix.dm.builder.lambda.DependencyActivatorBase.component;
 
 import java.util.Dictionary;

Added: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceDependencyInjectionTest.java
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceDependencyInjectionTest.java?rev=1725381&view=auto
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceDependencyInjectionTest.java
 (added)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceDependencyInjectionTest.java
 Mon Jan 18 23:07:15 2016
@@ -0,0 +1,157 @@
+/*
+ * 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.felix.dm.builder.lambda.itest;
+
+import static 
org.apache.felix.dm.builder.lambda.DependencyActivatorBase.component;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.junit.Assert;
+
+/**
+ * @author <a href="mailto:[email protected]";>Felix Project Team</a>
+ */
+public class ServiceDependencyInjectionTest extends TestBase {
+    public void testServiceInjection() {
+        DependencyManager m = getDM();
+        Ensure e = new Ensure();
+        // create a service provider and consumer
+        ServiceProvider provider = new ServiceProvider(e);
+        Component sp = 
component(m).impl(provider).provides(ServiceInterface2.class.getName()).build();
+        Component sc = component(m).impl(new 
ServiceConsumer()).withService(ServiceInterface2.class).build();
+           
+        Component sc2 = component(m) // all dependencies are optional
+            .impl(new ServiceConsumerNamedInjection(false, false)) 
+            .withService(ServiceInterface2.class, 
s->s.optional().autoConfig("m_service"))
+            .withService(ServiceInterface2.class, 
s->s.optional().autoConfig("m_service2"))
+            .withService(ServiceInterface2.class, 
s->s.optional().autoConfig("m_service3"))
+            .build();
+        
+        Component sc3 = component(m) // second dependency is required, first 
and third are optional
+            .impl(new ServiceConsumerNamedInjection(false, false))
+            .withService(ServiceInterface2.class, 
s->s.optional().autoConfig("m_service"))
+            .withService(ServiceInterface2.class, 
s->s.required().autoConfig("m_service2"))
+            .withService(ServiceInterface2.class, 
s->s.optional().autoConfig("m_service3"))
+            .build();
+        
+        Component sc4 = component(m)
+            .impl(new ServiceConsumerNamedInjection(true, false)).build();
+        Component sc5 = component(m)
+            .impl(new ServiceConsumerNamedInjection(true, true)).build();
+        m.add(sp);
+        m.add(sc);
+        m.remove(sc);
+        m.add(sc2);
+        m.remove(sc2);
+        m.add(sc3);
+        m.remove(sc4);
+        m.add(sc4);
+        m.remove(sc4);
+        m.add(sc5);
+        m.remove(sc5);
+        m.remove(sp);
+        e.waitForStep(11, 5000);
+        m.clear();
+    }
+    
+    static interface ServiceInterface {
+        public void invoke();
+    }
+    
+    static interface ServiceInterface2 extends ServiceInterface {
+        public void invoke2();
+    }
+
+    static class ServiceProvider implements ServiceInterface2 {
+        private final Ensure m_ensure;
+        private Ensure.Steps m_invokeSteps = new Ensure.Steps(4, 5, 7, 8, 10, 
11, 13, 14);
+        private Ensure.Steps m_invoke2Steps = new Ensure.Steps(1, 2, 3, 6, 9, 
12);
+        
+        public ServiceProvider(Ensure e) {
+            m_ensure = e;
+        }
+
+        public void invoke() {
+            System.out.println("invoke");
+            m_ensure.steps(m_invokeSteps);
+        }
+        
+        public void invoke2() {
+            System.out.println("invoke2");
+            m_ensure.steps(m_invoke2Steps);
+        }
+    }
+
+    static class ServiceConsumer {
+        private volatile ServiceInterface2 m_service;
+        private volatile ServiceInterface2 m_service2;
+        
+        public void init() {
+            // invoke the second method of the interface via both injected 
members, to ensure
+            // neither of them is a null object (or null)
+            m_service.invoke2();
+            m_service2.invoke2();
+            Assert.assertEquals("Both members should have been injected with 
the same service.", m_service, m_service2);
+        }
+    }
+
+    class ServiceConsumerNamedInjection {
+        private volatile ServiceInterface2 m_service;
+        private volatile ServiceInterface m_service2;
+        private volatile Object m_service3;
+        private final boolean m_secondDependencyRequired;
+        private final boolean m_instanceBound;
+        
+        ServiceConsumerNamedInjection(boolean instanceBound, boolean 
withSecondRequired) {
+            m_secondDependencyRequired = withSecondRequired;
+            m_instanceBound = instanceBound;
+        }
+
+        public void init(Component c) {
+            if (m_instanceBound) {
+                DependencyManager m = c.getDependencyManager();
+                
c.add(m.createServiceDependency().setService(ServiceInterface2.class).setRequired(false).setAutoConfig("m_service"),
+                    
m.createServiceDependency().setService(ServiceInterface2.class).setRequired(m_secondDependencyRequired).setAutoConfig("m_service2"),
+                    
m.createServiceDependency().setService(ServiceInterface2.class).setRequired(false).setAutoConfig("m_service3"));
+            } else {
+                check();
+            }
+        }
+        
+        public void start() {
+            if (m_instanceBound) {
+                check();
+            }
+        }
+        
+        public void check() {
+            warn("ServiceConsumerNamedInjectionInstanceBound: m_service=%s, 
m_service2=%s, m_service3=%s", m_service, m_service2, m_service3);
+            // invoke the second method
+            m_service.invoke2();
+            // invoke the first method (twice)
+            m_service2.invoke();
+            ((ServiceInterface) m_service3).invoke();
+            Assert.assertNotNull("Should have been injected", m_service);
+            Assert.assertNotNull("Should have been injected", m_service2);
+            Assert.assertNotNull("Should have been injected", m_service3);
+            Assert.assertEquals("Members should have been injected with the 
same service.", m_service, m_service2);
+            Assert.assertEquals("Members should have been injected with the 
same service.", m_service, m_service3);          
+        }
+    }
+}

Added: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceDependencyPropagateTest.java
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceDependencyPropagateTest.java?rev=1725381&view=auto
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceDependencyPropagateTest.java
 (added)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceDependencyPropagateTest.java
 Mon Jan 18 23:07:15 2016
@@ -0,0 +1,161 @@
+/*
+ * 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.felix.dm.builder.lambda.itest;
+
+import static org.apache.felix.dm.builder.lambda.Cb.ADD;
+import static 
org.apache.felix.dm.builder.lambda.DependencyActivatorBase.component;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Validates ServiceDependency service properties propagation.
+ * 
+ * @author <a href="mailto:[email protected]";>Felix Project Team</a>
+ */
+@SuppressWarnings({"unchecked", "rawtypes", "serial"})
+public class ServiceDependencyPropagateTest extends TestBase {
+    /**
+     * Checks that a ServiceDependency propagates the dependency service 
properties to the provided service properties.
+     */
+    public void testServiceDependencyPropagate() {
+        DependencyManager m = getDM();
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        
+        Component c1 = component(m)
+                      .impl(new C1(e))
+                      .withService(C2.class, s->s.cb("bind", null)).build();
+
+        Component c2 = component(m)
+                      .provides(C2.class.getName(), new Hashtable() {{ 
put("foo", "bar"); }})
+                      .impl(new C2())
+                      .withService(C3.class, s->s.propagate()).build();
+
+        Component c3 = component(m)
+                      .provides(C3.class.getName(), new Hashtable() {{ 
put("foo2", "bar2"); put("foo", "overriden");}})
+                      .impl(new C3()).build();
+        
+        m.add(c1);
+        m.add(c2);
+        m.add(c3);
+
+        e.waitForStep(3, 10000);
+        
+        m.remove(c3);
+        m.remove(c2);
+        m.remove(c1);
+        m.clear();
+    }
+    
+    /**
+     * Checks that a ServiceDependency propagates the dependency service 
properties to the provided service properties,
+     * using a callback method.
+     */
+    public void testServiceDependencyPropagateCallback() {
+        DependencyManager m = getDM();
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        Component c1 = component(m)
+                      .impl(new C1(e))
+                      .withService(C2.class, s->s.cb("bind")).build();
+
+        C2 c2Impl = new C2();
+        Component c2 = component(m)
+                      .provides(C2.class.getName(), new Hashtable() {{ 
put("foo", "bar"); }})
+                      .impl(c2Impl)
+                      .withService(C3.class, s->s.propagate(c2Impl, 
"getServiceProperties")).build();
+        
+        Component c3 = component(m)
+                      .provides(C3.class.getName())
+                      .impl(new C3()).build();
+        
+        m.add(c1);
+        m.add(c2);
+        m.add(c3);
+
+        e.waitForStep(3, 10000);
+        m.clear();
+    }
+    
+    public void testServiceDependencyPropagateCallbackRef() {
+        DependencyManager m = getDM();
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        Component c1 = component(m)
+                      .impl(new C1(e))
+                      .withService(C2.class, s->s.cb(ADD, C1::bind)).build();
+
+        C2 c2Impl = new C2();
+        Component c2 = component(m)
+                      .provides(C2.class.getName(), new Hashtable() {{ 
put("foo", "bar"); }})
+                      .impl(c2Impl)
+                      .withService(C3.class, 
s->s.propagate(c2Impl::getServiceProperties)).build();
+        
+        Component c3 = component(m)
+                      .provides(C3.class.getName())
+                      .impl(new C3()).build();
+        
+        m.add(c1);
+        m.add(c2);
+        m.add(c3);
+
+        e.waitForStep(3, 10000);
+        m.clear();
+    }
+
+    public static class C1 {
+        private Map m_props;
+        private Ensure m_ensure;
+        
+        C1(Ensure ensure) {
+            m_ensure = ensure;
+        }
+
+        void bind(C2 c2, Map props) {
+            m_props = props;
+        }
+        
+        void start() {
+            m_ensure.step(1);
+            if ("bar".equals(m_props.get("foo"))) { // "foo=overriden" from C2 
should not override our own "foo" property
+                m_ensure.step(2);
+            }
+            if ("bar2".equals(m_props.get("foo2"))) {
+                m_ensure.step(3);
+            }
+        }
+    }
+    
+    public static class C2 {
+      C3 m_c3;
+      
+      public Dictionary getServiceProperties(ServiceReference ref) {
+          return new Hashtable() {{ put("foo2", "bar2"); put("foo", 
"overriden"); }};
+      }
+    }
+    
+    public static class C3 {
+    }
+}

Added: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/TemporalServiceDependencyTest.java
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/TemporalServiceDependencyTest.java?rev=1725381&view=auto
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/TemporalServiceDependencyTest.java
 (added)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/TemporalServiceDependencyTest.java
 Mon Jan 18 23:07:15 2016
@@ -0,0 +1,267 @@
+/*
+ * 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.felix.dm.builder.lambda.itest;
+
+import static 
org.apache.felix.dm.builder.lambda.DependencyActivatorBase.component;
+import static 
org.apache.felix.dm.builder.lambda.DependencyActivatorBase.serviceDependency;
+
+import java.util.Hashtable;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.ServiceDependency;
+import org.junit.Assert;
+
+/**
+ * @author <a href="mailto:[email protected]";>Felix Project Team</a>
+ */
+@SuppressWarnings({"unchecked", "rawtypes", "serial"})
+public class TemporalServiceDependencyTest extends TestBase {
+    public void testServiceConsumptionAndIntermittentAvailability() {
+        final DependencyManager m = getDM();
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        // create a service provider and consumer
+        TemporalServiceProvider provider = new TemporalServiceProvider(e);
+        Component sp = 
component(m).impl(provider).provides(TemporalServiceInterface.class.getName()).build();
+        TemporalServiceProvider2 provider2 = new TemporalServiceProvider2(e);
+        Component sp2 = 
component(m).impl(provider2).provides(TemporalServiceInterface.class.getName()).build();
+        TemporalServiceConsumer consumer = new TemporalServiceConsumer(e);
+        Component sc = 
component(m).impl(consumer).withService(TemporalServiceInterface.class, 
s->s.timeout(10000)).build();
+        // add the service consumer
+        m.add(sc);
+        // now add the first provider
+        m.add(sp);
+        e.waitForStep(2, 5000);
+        // and remove it again (this should not affect the consumer yet)
+        m.remove(sp);
+        // now add the second provider
+        m.add(sp2);
+        e.step(3);
+        e.waitForStep(4, 5000);
+        // and remove it again
+        m.remove(sp2);
+        // finally remove the consumer
+        m.remove(sc);
+        // ensure we executed all steps inside the component instance
+        e.step(6);
+        m.clear();
+    }
+
+    public void 
testServiceConsumptionWithCallbackAndIntermittentAvailability() {
+        final DependencyManager m = getDM();
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        // create a service provider and consumer
+        TemporalServiceProvider provider = new TemporalServiceProvider(e);
+        Component sp = 
component(m).impl(provider).provides(TemporalServiceInterface.class.getName()).build();
+        TemporalServiceProvider2 provider2 = new TemporalServiceProvider2(e);
+        Component sp2 = 
component(m).impl(provider2).provides(TemporalServiceInterface.class.getName()).build();
+        TemporalServiceConsumerWithCallback consumer = new 
TemporalServiceConsumerWithCallback(e);
+        Component sc = 
component(m).impl(consumer).withService(TemporalServiceInterface.class, 
srv->srv.cb("add", "remove").timeout(10000)).build();
+            
+        // add the service consumer
+        m.add(sc);
+        // now add the first provider
+        m.add(sp);
+        e.waitForStep(2, 5000);
+        // and remove it again (this should not affect the consumer yet)
+        m.remove(sp);
+        // now add the second provider
+        m.add(sp2);
+        e.step(3);
+        e.waitForStep(4, 5000);
+        // and remove it again
+        m.remove(sp2);
+        // finally remove the consumer
+        m.remove(sc);
+        // Wait for the consumer.remove callback
+        e.waitForStep(6, 5000);
+        // ensure we executed all steps inside the component instance
+        e.step(7);
+        m.clear();
+    }
+
+    // Same test as 
testServiceConsumptionWithCallbackAndIntermittentAvailability, but the consumer 
is now
+    // an adapter for the Adaptee interface.
+    public void 
testFELIX4858_ServiceAdapterConsumptionWithCallbackAndIntermittentAvailability()
 {
+        final DependencyManager m = getDM();
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        // create a service provider and consumer
+        TemporalServiceProvider provider = new TemporalServiceProvider(e);
+        Component sp = 
component(m).impl(provider).provides(TemporalServiceInterface.class.getName()).build();
+        TemporalServiceProvider2 provider2 = new TemporalServiceProvider2(e);
+        Component sp2 = 
component(m).impl(provider2).provides(TemporalServiceInterface.class.getName()).build();
+        TemporalServiceConsumerAdapterWithCallback consumer = new 
TemporalServiceConsumerAdapterWithCallback(e);
+        Component sc = m.createAdapterService(Adaptee.class, 
null).setImplementation(consumer);
+        ServiceDependency temporalDep = serviceDependency(sc, 
TemporalServiceInterface.class).timeout(10000).cb("add", "remove").build();
+        sc.add(temporalDep);
+        Component adaptee = component(m).impl(new 
Adaptee()).provides(Adaptee.class.getName()).build();
+            
+        // add the adapter service consumer
+        m.add(sc);
+        // add the adaptee (the adapter service depends on it)
+        m.add(adaptee);
+        // now add the first provider
+        m.add(sp);
+        e.waitForStep(2, 5000);
+        // and remove it again (this should not affect the consumer yet)
+        m.remove(sp);
+        // now add the second provider
+        m.add(sp2);
+        e.step(3);
+        e.waitForStep(4, 5000);
+        // and remove it again
+        m.remove(sp2);
+        // finally remove the consumer
+        m.remove(sc);
+        // Wait for the consumer.remove callback
+        e.waitForStep(6, 5000);
+        // ensure we executed all steps inside the component instance
+        e.step(7);
+        m.clear();
+    }
+
+    public void testFelix4602_PropagateServiceInvocationException() {
+        final DependencyManager m = getDM();
+        final Ensure ensure = new Ensure();
+        Runnable provider = new Runnable() {
+               public void run() {
+                       throw new UncheckedException();
+               }
+        };
+        Hashtable props = new Hashtable();
+        props.put("target", getClass().getSimpleName());
+        Component providerComp = component(m)
+                       .provides(Runnable.class.getName(), props)
+                       .impl(provider).build();
+
+        Object consumer = new Object() {
+               volatile Runnable m_provider;
+               @SuppressWarnings("unused")
+            void start() {
+                       try {
+                               ensure.step(1);
+                               m_provider.run();
+                       } catch (UncheckedException e) {
+                               ensure.step(2);
+                       }
+               }
+        };
+        Component consumerComp = component(m)
+                       .impl(consumer)
+                       .withService(Runnable.class, 
s->s.timeout(5000).filter("(target=" + getClass().getSimpleName() + 
")")).build();
+        m.add(consumerComp);
+        m.add(providerComp);
+        ensure.waitForStep(2, 5000);
+        m.clear();
+    }
+    
+    static class UncheckedException extends RuntimeException {         
+    }
+
+    static interface TemporalServiceInterface {
+        public void invoke();
+    }
+
+    static class TemporalServiceProvider implements TemporalServiceInterface {
+        private final Ensure m_ensure;
+        public TemporalServiceProvider(Ensure e) {
+            m_ensure = e;
+        }
+        public void invoke() {
+            m_ensure.step(2);
+        }
+    }
+
+    static class TemporalServiceProvider2 implements TemporalServiceInterface {
+        protected final Ensure m_ensure;
+        public TemporalServiceProvider2(Ensure e) {
+            m_ensure = e;
+        }
+        public void invoke() {
+            m_ensure.step(4);
+        }
+    }
+
+    static class TemporalServiceConsumer implements Runnable {
+        protected volatile TemporalServiceInterface m_service;
+        protected final Ensure m_ensure;
+
+        public TemporalServiceConsumer(Ensure e) {
+            m_ensure = e;
+        }
+        
+        public void init() {
+            m_ensure.step(1);
+            Thread t = new Thread(this);
+            t.start();
+        }
+        
+        public void run() {
+            m_service.invoke();
+            m_ensure.waitForStep(3, 15000);
+            m_service.invoke();
+        }
+        
+        public void destroy() {
+            m_ensure.step(5);
+        }
+    }
+    
+    static class TemporalServiceConsumerWithCallback extends 
TemporalServiceConsumer {
+        public TemporalServiceConsumerWithCallback(Ensure e) {
+            super(e);
+        }
+        
+        public void add(TemporalServiceInterface service) {
+            m_service = service;
+        }
+        
+        public void remove(TemporalServiceInterface service) {
+            Assert.assertTrue(m_service == service);
+            m_ensure.step(6);
+        }
+    }
+    
+    public static class Adaptee {       
+    }
+       
+    static class TemporalServiceConsumerAdapterWithCallback extends 
TemporalServiceConsumer {
+        volatile Adaptee m_adaptee;
+        
+        public TemporalServiceConsumerAdapterWithCallback(Ensure e) {
+            super(e);
+        }
+        
+        public void start() {
+            Assert.assertTrue(m_adaptee != null);
+        }
+        
+        public void add(TemporalServiceInterface service) {
+            m_service = service;
+        }
+        
+        public void remove(TemporalServiceInterface service) {
+            Assert.assertTrue(m_service == service);
+            m_ensure.step(6);
+        }
+    }
+}

Modified: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/ServiceDependencyBuilder.java
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/ServiceDependencyBuilder.java?rev=1725381&r1=1725380&r2=1725381&view=diff
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/ServiceDependencyBuilder.java
 (original)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/ServiceDependencyBuilder.java
 Mon Jan 18 23:07:15 2016
@@ -87,7 +87,6 @@ public interface ServiceDependencyBuilde
      * @return
      */
     ServiceDependencyBuilder<S> propagate(BiFunction<ServiceReference<S>, S, 
Dictionary<String, Object>> propagate);
-
     
     /**
      * Sets the default implementation if the service is not available.
@@ -95,4 +94,14 @@ public interface ServiceDependencyBuilde
         * @return this builder
      */
     ServiceDependencyBuilder<S> defImpl(Object defaultImpl);
+    
+    /**
+     * Sets a timeout for this dependency. A timed dependency blocks the 
invoker thread is the required dependency is currently unavailable, until it 
comes up again.
+     * @param timeout the timeout to wait in milliseconds when the service 
disappears. If the timeout expires, an IllegalStateException is thrown
+     * when the missing service is invoked.
+     * 
+     * @return this builder
+     */
+    ServiceDependencyBuilder<S> timeout(long timeout);
+    
 }
\ No newline at end of file

Modified: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ServiceDependencyBuilderImpl.java
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ServiceDependencyBuilderImpl.java?rev=1725381&r1=1725380&r2=1725381&view=diff
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ServiceDependencyBuilderImpl.java
 (original)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ServiceDependencyBuilderImpl.java
 Mon Jan 18 23:07:15 2016
@@ -21,6 +21,7 @@ public class ServiceDependencyBuilderImp
     private Object m_propagateInstance;
     private String m_propagateMethod;
     private Object m_defaultImpl;
+    private long m_timeout = -1;
 
     public ServiceDependencyBuilderImpl(Component component, Class<S> service) 
{
         super(service);
@@ -98,6 +99,11 @@ public class ServiceDependencyBuilderImp
         return this;
     }
 
+    public ServiceDependencyBuilder<S> timeout(long timeout) {
+        m_timeout = timeout;
+        return this;
+    }
+
        // Build final ServiceDependency object.
     @Override
     public ServiceDependency build() {
@@ -105,7 +111,7 @@ public class ServiceDependencyBuilderImp
         if (m_ref != null && m_filter != null) {
             throw new IllegalArgumentException("Can not set ref and filter at 
the same time");
         }
-        ServiceDependency sd = dm.createServiceDependency();
+        ServiceDependency sd = m_timeout > -1 ? 
dm.createTemporalServiceDependency(m_timeout) : dm.createServiceDependency();
         if (m_ref != null) {
             sd.setService(m_serviceIface, m_ref);
         } else {



Reply via email to