Added: 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=1724333&view=auto ============================================================================== --- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AspectWithPropagationTest.java (added) +++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AspectWithPropagationTest.java Tue Jan 12 22:45:36 2016 @@ -0,0 +1,751 @@ +/* + * 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.aspect; +import static org.apache.felix.dm.builder.lambda.DependencyActivatorBase.component; + +import java.util.Dictionary; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Map; +import java.util.Random; +import java.util.Set; + +import org.apache.felix.dm.Component; +import org.apache.felix.dm.DependencyManager; +import org.junit.Assert; +import org.osgi.framework.ServiceReference; +import org.osgi.framework.ServiceRegistration; + + +/** + * Test for aspects with service properties propagations. + * + * @author <a href="mailto:[email protected]">Felix Project Team</a> + */ +@SuppressWarnings({"rawtypes", "unchecked", "unused"}) +public class AspectWithPropagationTest extends TestBase { + private final static int ASPECTS = 3; + private final Set<Integer> _randoms = new HashSet<Integer>(); + private final Random _rnd = new Random(); + private static Ensure m_invokeStep; + private static Ensure m_changeStep; + + /** + * This test does the following: + * + * - Create S service with property "p=s" + * - Create SA (aspect of S) with property "p=aspect" + * - Create Client, depending on S (actually, on SA). + * - Client should see SA with properties p=aspect + * - Change S service property with "p=smodified": the Client should be changed with SA(p=aspect) + * - Change aspect service property with "p=aspectmodified": The client should be changed with SA(p=aspectmodified) + */ + public void testAspectsWithPropagationNotOverriding() { + System.out.println("----------- Running testAspectsWithPropagationNotOverriding ..."); + DependencyManager m = getDM(); + m_invokeStep = new Ensure(); + + // Create our original "S" service. + S s = new S() { + public void invoke() { + } + }; + Component sComp = component(m, c->c.autoAdd(false).impl(s).provides(S.class).properties(p -> "s")); + + // Create SA (aspect of S) + S sa = new S() { + volatile S m_s; + public void invoke() { + } + }; + Component saComp = aspect(m, S.class, a->a.autoAdd(false).rank(1).impl(sa).properties(p -> "aspect")); + + // Create client depending on S + Object client = new Object() { + int m_changeCount; + void add(Map props, S s) { + Assert.assertEquals("aspect", props.get("p")); + m_invokeStep.step(1); + } + + void change(Map props, S s) { + switch (++m_changeCount) { + case 1: + Assert.assertEquals("aspect", props.get("p")); + m_invokeStep.step(2); + break; + case 2: + Assert.assertEquals("aspectmodified", props.get("p")); + m_invokeStep.step(3); + } + } + }; + Component clientComp = component(m, c->c.autoAdd(false).impl(client).withService(S.class, srv->srv.cb("add", "change", null))); + + // Add components in dependency manager + m.add(sComp); + m.add(saComp); + m.add(clientComp); + + // client should have been added with SA aspect + m_invokeStep.waitForStep(1, 5000); + + // now change s "p=s" to "p=smodified": client should not see it + Hashtable props = new Hashtable(); + props.put("p", "smodified"); + sComp.setServiceProperties(props); + m_invokeStep.waitForStep(2, 5000); + + // now change sa aspect "p=aspect" to "p=aspectmodified": client should see it + props = new Hashtable(); + props.put("p", "aspectmodified"); + saComp.setServiceProperties(props); + m_invokeStep.waitForStep(3, 5000); + + // remove components + m.remove(clientComp); + m.remove(saComp); + m.remove(sComp); + } + + /** + * This test does the following: + * + * - Create S service + * - Create some S Aspects + * - Create a Client, depending on S (actually, on the top-level S aspect) + * - Client has a "change" callback in order to track S service properties modifications. + * - First, invoke Client.invoke(): all S aspects, and finally original S service must be invoked orderly. + * - Modify S original service properties, and check if all aspects, and the client has been orderly called in their "change" callback. + * - Modify the First lowest ranked aspect (rank=1), and check if all aspects, and client have been orderly called in their "change" callback. + */ + public void testAspectsWithPropagation() { + System.out.println("----------- Running testAspectsWithPropagation ..."); + DependencyManager m = getDM(); + // helper class that ensures certain steps get executed in sequence + m_invokeStep = new Ensure(); + + // Create our original "S" service. + Dictionary props = new Hashtable(); + props.put("foo", "bar"); + Component s = m.createComponent() + .setImplementation(new SImpl()) + .setInterface(S.class.getName(), props); + + // Create an aspect aware client, depending on "S" service. + Client clientImpl; + Component client = m.createComponent() + .setImplementation((clientImpl = new Client())) + .add(m.createServiceDependency() + .setService(S.class) + .setRequired(true) + .setCallbacks("add", "change", "remove", "swap")); + + // Create some "S" aspects + Component[] aspects = new Component[ASPECTS]; + for (int rank = 1; rank <= ASPECTS; rank ++) { + aspects[rank-1] = m.createAspectService(S.class, null, rank, "add", "change", "remove", "swap") + .setImplementation(new A("A" + rank, rank)); + props = new Hashtable(); + props.put("a" + rank, "v" + rank); + aspects[rank-1].setServiceProperties(props); + } + + // Register client + m.add(client); + + // Randomly register aspects and original service + boolean originalServiceAdded = false; + for (int i = 0; i < ASPECTS; i ++) { + int index = getRandomAspect(); + m.add(aspects[index]); + if (! originalServiceAdded && _rnd.nextBoolean()) { + m.add(s); + originalServiceAdded = true; + } + } + if (! originalServiceAdded) { + m.add(s); + } + + // All set, check if client has inherited from top level aspect properties + original service properties + Map check = new HashMap(); + check.put("foo", "bar"); + for (int i = 1; i < (ASPECTS - 1); i ++) { + check.put("a" + i, null); // we must not inherit from lower ranks, only from the top-level aspect. + } + check.put("a" + ASPECTS, "v" + ASPECTS); + checkServiceProperties(check, clientImpl.getServiceProperties()); + + // Now invoke client, which orderly calls all aspects in the chain, and finally the original service "S". + System.out.println("-------------------------- Invoking client."); + clientImpl.invoke(); + m_invokeStep.waitForStep(ASPECTS+1, 5000); + + // Now, change original service "S" properties: this will orderly trigger "change" callbacks on aspects, and on client. + System.out.println("-------------------------- Modifying original service properties."); + m_changeStep = new Ensure(); + props = new Hashtable(); + props.put("foo", "barModified"); + s.setServiceProperties(props); + + // Check if aspects and client have been orderly called in their "changed" callback + m_changeStep.waitForStep(ASPECTS+1, 5000); + + // Check if modified "foo" original service property has been propagated + check = new HashMap(); + check.put("foo", "barModified"); + for (int i = 1; i < (ASPECTS - 1); i ++) { + check.put("a" + i, null); // we must not inherit from lower ranks, only from the top-level aspect. + } + check.put("a" + ASPECTS, "v" + ASPECTS); // we only see top-level aspect service properties + checkServiceProperties(check, clientImpl.getServiceProperties()); + + // Now, change the top-level ranked aspect: it must propagate to all upper aspects, as well as to the client + System.out.println("-------------------------- Modifying top-level aspect service properties."); + + m_changeStep = new Ensure(); + for (int i = 1; i <= ASPECTS; i ++) { + m_changeStep.step(i); // only client has to be changed. + } + props = new Hashtable(); + props.put("a" + ASPECTS, "v" + ASPECTS + "-Modified"); + aspects[ASPECTS-1].setServiceProperties(props); // That triggers change callbacks for upper aspects (with rank >= 2) + m_changeStep.waitForStep(ASPECTS+1, 5000); // check if client have been changed. + + // Check if top level aspect service properties have been propagated up to the client. + check = new HashMap(); + check.put("foo", "barModified"); + for (int i = 1; i < (ASPECTS - 1); i ++) { + check.put("a" + i, null); // we must not inherit from lower ranks, only from the top-level aspect. + } + check.put("a" + ASPECTS, "v" + ASPECTS + "-Modified"); + checkServiceProperties(check, clientImpl.getServiceProperties()); + + // Clear all components. + m_changeStep = null; + m.clear(); + } + + /** + * This test does the following: + * + * - Create S service + * - Create some S Aspects without any callbacks (add/change/remove/swap) + * - Create a Client, depending on S (actually, on the top-level S aspect) + * - Client has a "change" callack in order to track S service properties modifications. + * - First, invoke Client.invoke(): all S aspects, and finally original S service must be invoked orderly. + * - Modify S original service properties, and check if the client has been called in its "change" callback. + */ + public void testAspectsWithPropagationAndNoCallbacks() { + System.out.println("----------- Running testAspectsWithPropagation ..."); + DependencyManager m = getDM(); + // helper class that ensures certain steps get executed in sequence + m_invokeStep = new Ensure(); + + // Create our original "S" service. + Dictionary props = new Hashtable(); + props.put("foo", "bar"); + Component s = m.createComponent() + .setImplementation(new SImpl()) + .setInterface(S.class.getName(), props); + + // Create an aspect aware client, depending on "S" service. + Client clientImpl; + Component client = m.createComponent() + .setImplementation((clientImpl = new Client())) + .add(m.createServiceDependency() + .setService(S.class) + .setRequired(true) + .setCallbacks("add", "change", "remove")); + + // Create some "S" aspects + Component[] aspects = new Component[ASPECTS]; + for (int rank = 1; rank <= ASPECTS; rank ++) { + aspects[rank-1] = m.createAspectService(S.class, null, rank) + .setImplementation(new A("A" + rank, rank)); + props = new Hashtable(); + props.put("a" + rank, "v" + rank); + aspects[rank-1].setServiceProperties(props); + } + + // Register client + m.add(client); + + // Randomly register aspects and original service + boolean originalServiceAdded = false; + for (int i = 0; i < ASPECTS; i ++) { + int index = getRandomAspect(); + m.add(aspects[index]); + if (! originalServiceAdded && _rnd.nextBoolean()) { + m.add(s); + originalServiceAdded = true; + } + } + if (! originalServiceAdded) { + m.add(s); + } + + // All set, check if client has inherited from top level aspect properties + original service properties + Map check = new HashMap(); + check.put("foo", "bar"); + for (int i = 1; i < (ASPECTS - 1); i ++) { + check.put("a" + i, null); // we must not inherit from lower ranks, only from the top-level aspect. + } + check.put("a" + ASPECTS, "v" + ASPECTS); + checkServiceProperties(check, clientImpl.getServiceProperties()); + + // Now invoke client, which orderly calls all aspects in the chain, and finally the original service "S". + System.out.println("-------------------------- Invoking client."); + clientImpl.invoke(); + m_invokeStep.waitForStep(ASPECTS+1, 5000); + + // Now, change original service "S" properties: this will orderly trigger "change" callbacks on aspects, and on client. + System.out.println("-------------------------- Modifying original service properties."); + m_changeStep = new Ensure(); + for (int i = 1; i <= ASPECTS; i ++) { + m_changeStep.step(i); // skip aspects, which have no "change" callbacks. + } + props = new Hashtable(); + props.put("foo", "barModified"); + s.setServiceProperties(props); + + // Check if aspects and client have been orderly called in their "changed" callback + m_changeStep.waitForStep(ASPECTS+1, 5000); + + // Check if modified "foo" original service property has been propagated + check = new HashMap(); + check.put("foo", "barModified"); + for (int i = 1; i < (ASPECTS - 1); i ++) { + check.put("a" + i, null); // we must not inherit from lower ranks, only from the top-level aspect. + } + check.put("a" + ASPECTS, "v" + ASPECTS); // we only see top-level aspect service properties + checkServiceProperties(check, clientImpl.getServiceProperties()); + + // Clear all components. + m_changeStep = null; + m.clear(); + } + + /** + * This test does the following: + * + * - Create S service + * - Create some S Aspects + * - Create S2 Adapter, which adapts S to S2 + * - Create Client2, which depends on S2. Client2 listens to S2 property change events. + * - Now, invoke Client2.invoke(): all S aspects, and finally original S service must be invoked orderly. + * - Modify S original service properties, and check if all aspects, S2 Adapter, and Client2 have been orderly called in their "change" callback. + */ + public void testAdapterWithAspectsAndPropagation() { + System.out.println("----------- Running testAdapterWithAspectsAndPropagation ..."); + + DependencyManager m = getDM(); + m_invokeStep = new Ensure(); + + // Create our original "S" service. + Dictionary props = new Hashtable(); + props.put("foo", "bar"); + Component s = m.createComponent() + .setImplementation(new SImpl()) + .setInterface(S.class.getName(), props); + + // Create some "S" aspects + Component[] aspects = new Component[ASPECTS]; + for (int rank = 1; rank <= ASPECTS; rank ++) { + aspects[rank-1] = m.createAspectService(S.class, null, rank, "add", "change", "remove", "swap") + .setImplementation(new A("A" + rank, rank)); + props = new Hashtable(); + props.put("a" + rank, "v" + rank); + aspects[rank-1].setServiceProperties(props); + } + + // Create S2 adapter (which adapts S1 to S2 interface) + Component adapter = m.createAdapterService(S.class, null, "add", "change", "remove", "swap") + .setInterface(S2.class.getName(), null) + .setImplementation(new S2Impl()); + + // Create Client2, which depends on "S2" service. + Client2 client2Impl; + Component client2 = m.createComponent() + .setImplementation((client2Impl = new Client2())) + .add(m.createServiceDependency() + .setService(S2.class) + .setRequired(true) + .setCallbacks("add", "change", null)); + + // Register client2 + m.add(client2); + + // Register S2 adapter + m.add(adapter); + + // Randomly register aspects, original service + boolean originalServiceAdded = false; + for (int i = 0; i < ASPECTS; i ++) { + int index = getRandomAspect(); + m.add(aspects[index]); + if (! originalServiceAdded && _rnd.nextBoolean()) { + m.add(s); + originalServiceAdded = true; + } + } + if (! originalServiceAdded) { + m.add(s); + } + + // Now invoke client2, which orderly calls all S1 aspects, then S1Impl, and finally S2 service + System.out.println("-------------------------- Invoking client2."); + client2Impl.invoke2(); + m_invokeStep.waitForStep(ASPECTS+2, 5000); + + // Now, change original service "S" properties: this will orderly trigger "change" callbacks on aspects, S2Impl, and Client2. + System.out.println("-------------------------- Modifying original service properties."); + m_changeStep = new Ensure(); + props = new Hashtable(); + props.put("foo", "barModified"); + s.setServiceProperties(props); + + // Check if aspects and Client2 have been orderly called in their "changed" callback + m_changeStep.waitForStep(ASPECTS+2, 5000); + + // Check if modified "foo" original service property has been propagated to Client2 + Map check = new HashMap(); + check.put("foo", "barModified"); + for (int i = 1; i < (ASPECTS - 1); i ++) { + check.put("a" + i, null); // we must not inherit from lower ranks, only from the top-level aspect. + } + check.put("a" + ASPECTS, "v" + ASPECTS); + checkServiceProperties(check, client2Impl.getServiceProperties()); + + // Clear all components. + m_changeStep = null; + m.clear(); + } + + /** + * This test does the following: + * + * - Create S service + * - Create some S Aspects without any callbacks (add/change/remove) + * - Create S2 Adapter, which adapts S to S2 (but does not have any add/change/remove callbacks) + * - Create Client2, which depends on S2. Client2 listens to S2 property change events. + * - Now, invoke Client2.invoke(): all S aspects, and finally original S service must be invoked orderly. + * - Modify S original service properties, and check if all aspects, S2 Adapter, and Client2 have been orderly called in their "change" callback. + */ + public void testAdapterWithAspectsAndPropagationNoCallbacks() { + System.out.println("----------- Running testAdapterWithAspectsAndPropagationNoCallbacks ..."); + + DependencyManager m = getDM(); + m_invokeStep = new Ensure(); + + // Create our original "S" service. + Dictionary props = new Hashtable(); + props.put("foo", "bar"); + Component s = m.createComponent() + .setImplementation(new SImpl()) + .setInterface(S.class.getName(), props); + + // Create some "S" aspects + Component[] aspects = new Component[ASPECTS]; + for (int rank = 1; rank <= ASPECTS; rank ++) { + aspects[rank-1] = m.createAspectService(S.class, null, rank) + .setImplementation(new A("A" + rank, rank)); + props = new Hashtable(); + props.put("a" + rank, "v" + rank); + aspects[rank-1].setServiceProperties(props); + } + + // Create S2 adapter (which adapts S1 to S2 interface) + Component adapter = m.createAdapterService(S.class, null) + .setInterface(S2.class.getName(), null) + .setImplementation(new S2Impl()); + + // Create Client2, which depends on "S2" service. + Client2 client2Impl; + Component client2 = m.createComponent() + .setImplementation((client2Impl = new Client2())) + .add(m.createServiceDependency() + .setService(S2.class) + .setRequired(true) + .setCallbacks("add", "change", null)); + + // Register client2 + m.add(client2); + + // Register S2 adapter + m.add(adapter); + + // Randomly register aspects, original service + boolean originalServiceAdded = false; + for (int i = 0; i < ASPECTS; i ++) { + int index = getRandomAspect(); + m.add(aspects[index]); + if (! originalServiceAdded && _rnd.nextBoolean()) { + m.add(s); + originalServiceAdded = true; + } + } + if (! originalServiceAdded) { + m.add(s); + } + + // Now invoke client2, which orderly calls all S1 aspects, then S1Impl, and finally S2 service + System.out.println("-------------------------- Invoking client2."); + client2Impl.invoke2(); + m_invokeStep.waitForStep(ASPECTS+2, 5000); + + // Now, change original service "S" properties: this will orderly trigger "change" callbacks on aspects, S2Impl, and Client2. + System.out.println("-------------------------- Modifying original service properties."); + m_changeStep = new Ensure(); + for (int i = 1; i <= ASPECTS+1; i ++) { + m_changeStep.step(i); // skip all aspects and the adapter + } + props = new Hashtable(); + props.put("foo", "barModified"); + s.setServiceProperties(props); + + // Check if Client2 has been called in its "changed" callback + m_changeStep.waitForStep(ASPECTS+2, 5000); + + // Check if modified "foo" original service property has been propagated to Client2 + Map check = new HashMap(); + check.put("foo", "barModified"); + for (int i = 1; i < (ASPECTS - 1); i ++) { + check.put("a" + i, null); // we must not inherit from lower ranks, only from the top-level aspect. + } + check.put("a" + ASPECTS, "v" + ASPECTS); + checkServiceProperties(check, client2Impl.getServiceProperties()); + + // Clear all components. + m_changeStep = null; + m.clear(); + } + + private void checkServiceProperties(Map<?, ?> check, Dictionary properties) { + for (Object key : check.keySet()) { + Object val = check.get(key); + if (val == null) { + Assert.assertNull(properties.get(key)); + } else { + Assert.assertEquals(val, properties.get(key)); + } + } + } + + private int getRandomAspect() { + int index = 0; + do { + index = _rnd.nextInt(ASPECTS); + } while (_randoms.contains(new Integer(index))); + _randoms.add(new Integer(index)); + return index; + } + + // S Service + public static interface S { + public void invoke(); + } + + // S ServiceImpl + static class SImpl implements S { + public SImpl() { + } + + public String toString() { + return "S"; + } + + public void invoke() { + m_invokeStep.step(ASPECTS+1); + } + } + + // S Aspect + static class A implements S { + private final String m_name; + private volatile ServiceRegistration m_registration; + private volatile S m_next; + private final int m_rank; + + public A(String name, int rank) { + m_name = name; + m_rank = rank; + } + + public String toString() { + return m_name; + } + + public void invoke() { + int rank = ServiceUtil.getRanking(m_registration.getReference()); + m_invokeStep.step(ASPECTS - rank + 1); + m_next.invoke(); + } + + public void add(ServiceReference ref, S s) { + System.out.println("+++ A" + m_rank + ".add:" + s + "/" + ServiceUtil.toString(ref)); + m_next = s; + } + + public void swap(ServiceReference oldSRef, S oldS, ServiceReference newSRef, S newS) { + System.out.println("+++ A" + m_rank + ".swap: new=" + newS + ", props=" + ServiceUtil.toString(newSRef)); + Assert.assertTrue(m_next == oldS); + m_next = newS; + } + + public void change(ServiceReference props, S s) { + System.out.println("+++ A" + m_rank + ".change: s=" + s + ", props=" + ServiceUtil.toString(props)); + if (m_changeStep != null) { + int rank = ServiceUtil.getRanking(m_registration.getReference()); + m_changeStep.step(rank); + } + } + + public void remove(ServiceReference props, S s) { + System.out.println("+++ A" + m_rank + ".remove: " + s + ", props=" + ServiceUtil.toString(props)); + } + } + + // Aspect aware client, depending of "S" service aspects. + static class Client { + private volatile S m_s; + private volatile ServiceReference m_sRef; + + public Client() { + } + + public Dictionary getServiceProperties() { + Dictionary props = new Hashtable(); + for (String key : m_sRef.getPropertyKeys()) { + props.put(key, m_sRef.getProperty(key)); + } + return props; + } + + public void invoke() { + m_s.invoke(); + } + + public String toString() { + return "Client"; + } + + public void add(ServiceReference ref, S s) { + System.out.println("+++ Client.add: " + s + "/" + ServiceUtil.toString(ref)); + m_s = s; + m_sRef = ref; + } + + public void swap(ServiceReference oldSRef, S oldS, ServiceReference newSRef, S newS) { + System.out.println("+++ Client.swap: m_s = " + m_s + ", old=" + oldS + ", oldProps=" + ServiceUtil.toString(oldSRef) + ", new=" + newS + ", props=" + ServiceUtil.toString(newSRef)); + Assert.assertTrue(m_s == oldS); + m_s = newS; + m_sRef = newSRef; + } + + public void change(ServiceReference properties, S s) { + System.out.println("+++ Client.change: s=" + s + ", props=" + ServiceUtil.toString(properties)); + if (m_changeStep != null) { + m_changeStep.step(ASPECTS+1); + } + } + + public void remove(ServiceReference props, S s) { + System.out.println("+++ Client.remove: " + s + ", props=" + ServiceUtil.toString(props)); + } + } + + // S2 Service + public static interface S2 { + public void invoke2(); + } + + // S2 impl, which adapts S1 interface to S2 interface + static class S2Impl implements S2 { + private volatile S m_s; // we shall see top-level aspect on S service + + public void add(ServiceReference ref, S s) { + System.out.println("+++ S2Impl.add: " + s + "/" + ServiceUtil.toString(ref)); + m_s = s; + } + + public void swap(ServiceReference oldSRef, S oldS, ServiceReference newSRef, S newS) { + System.out.println("+++ S2Impl.swap: new=" + newS + ", props=" + ServiceUtil.toString(newSRef)); + m_s = newS; + } + + public void change(ServiceReference properties, S s) { + System.out.println("+++ S2Impl.change: s=" + s + ", props=" + ServiceUtil.toString(properties)); + if (m_changeStep != null) { + m_changeStep.step(ASPECTS+1); + } + } + + public void remove(ServiceReference props, S s) { + System.out.println("+++ S2Impl.remove: " + s + ", props=" + ServiceUtil.toString(props)); + } + + public void invoke2() { + m_s.invoke(); + m_invokeStep.step(ASPECTS + 2); // All aspects, and S1Impl have been invoked + } + + public String toString() { + return "S2"; + } + } + + // Client2 depending on S2. + static class Client2 { + private volatile S2 m_s2; + private volatile ServiceReference m_s2Ref; + + public Dictionary getServiceProperties() { + Dictionary props = new Hashtable(); + for (String key : m_s2Ref.getPropertyKeys()) { + props.put(key, m_s2Ref.getProperty(key)); + } + return props; + } + + public void invoke2() { + m_s2.invoke2(); + } + + public String toString() { + return "Client2"; + } + + public void add(ServiceReference ref, S2 s2) { + System.out.println("+++ Client2.add: " + s2 + "/" + ServiceUtil.toString(ref)); + m_s2 = s2; + m_s2Ref = ref; + } + + public void change(ServiceReference props, S2 s2) { + System.out.println("+++ Client2.change: s2=" + s2 + ", props=" + ServiceUtil.toString(props)); + if (m_changeStep != null) { + m_changeStep.step(ASPECTS + 2); // S1Impl, all aspects, and S2 adapters have been changed before us. + } + } + } +}
Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/BundleDependencyTest.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/BundleDependencyTest.java?rev=1724333&r1=1724332&r2=1724333&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/BundleDependencyTest.java (original) +++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/BundleDependencyTest.java Tue Jan 12 22:45:36 2016 @@ -18,12 +18,12 @@ */ package org.apache.felix.dm.builder.lambda.itest; -import org.junit.Assert; +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; import org.osgi.framework.Bundle; -import static org.apache.felix.dm.builder.lambda.DependencyActivatorBase.component; /** * @author <a href="mailto:[email protected]">Felix Project Team</a> @@ -35,8 +35,32 @@ public class BundleDependencyTest extend DependencyManager m = getDM(); // create a service provider and consumer MyConsumer c = new MyConsumer(); + Component consumer = component(m, comp -> comp.impl(c).withBundle(bundle -> bundle.cb("add", "remove"))); + + // check if at least one bundle was found + c.check(); + // remove the consumer again + m.remove(consumer); + // check if all bundles were removed correctly + c.doubleCheck(); + + // helper class that ensures certain steps get executed in sequence + Ensure e = new Ensure(); + String filter = "(Bundle-SymbolicName=" + BSN + ")"; + Component consumerWithFilter = component(m, comp -> comp.impl(new FilteredConsumer(e)) + .withBundle(bundle-> bundle.filter(filter).cb("add", "remove"))); + e.step(2); + // remove the consumer again + m.remove(consumerWithFilter); + e.step(4); + } + + public void testBundleDependenciesRef() { + DependencyManager m = getDM(); + // create a service provider and consumer + MyConsumer c = new MyConsumer(); Component consumer = component(m, comp -> comp - .impl(c).withBundle(bundle -> bundle.onAdd(MyConsumer::add).onRemove(MyConsumer::remove))); + .impl(c).withBundle(bundle -> bundle.cb(MyConsumer::add, MyConsumer::remove))); // check if at least one bundle was found c.check(); @@ -48,9 +72,8 @@ public class BundleDependencyTest extend // helper class that ensures certain steps get executed in sequence Ensure e = new Ensure(); String filter = "(Bundle-SymbolicName=" + BSN + ")"; - Component consumerWithFilter = component(m, comp -> comp - .impl(new FilteredConsumer(e)) - .withBundle(bundle-> bundle.filter(filter).onAdd(FilteredConsumer::add).onRemove(FilteredConsumer::remove))); + Component consumerWithFilter = component(m, comp -> comp.impl(new FilteredConsumer(e)) + .withBundle(bundle-> bundle.filter(filter).cb(FilteredConsumer::add, FilteredConsumer::remove))); e.step(2); // remove the consumer again m.remove(consumerWithFilter); @@ -62,33 +85,52 @@ public class BundleDependencyTest extend // helper class that ensures certain steps get executed in sequence Ensure e = new Ensure(); - Component consumerWithFilter = m.createComponent() - .setImplementation(new FilteredConsumerRequired(e)) - .add(m.createBundleDependency() - .setRequired(true) - .setFilter("(Bundle-SymbolicName=" + BSN + ")") - .setCallbacks("add", "remove") - ); - // add a consumer with a filter - m.add(consumerWithFilter); + Component consumerWithFilter = component(m, c -> c.impl(new FilteredConsumerRequired(e)) + .withBundle(b -> b.filter("(Bundle-SymbolicName=" + BSN + ")").cb("add", "remove"))); e.waitForStep(1, 5000); // remove the consumer again m.remove(consumerWithFilter); e.waitForStep(2, 5000); } + public void testRequiredBundleDependencyRef() { + DependencyManager m = getDM(); + + // helper class that ensures certain steps get executed in sequence + Ensure e = new Ensure(); + FilteredConsumerRequired impl = new FilteredConsumerRequired(e); + Component consumerWithFilter = component(m, c -> c.impl(impl) + .withBundle(b -> b.filter("(Bundle-SymbolicName=" + BSN + ")").cb(impl::add, impl::remove))); + e.waitForStep(1, 5000); + // remove the consumer again + m.remove(consumerWithFilter); + e.waitForStep(2, 5000); + } + public void testRequiredBundleDependencyWithComponentArgInCallbackMethod() { DependencyManager m = getDM(); // helper class that ensures certain steps get executed in sequence Ensure e = new Ensure(); - Component consumerWithFilter = m.createComponent() - .setImplementation(new FilteredConsumerRequiredWithComponentArg(e)) - .add(m.createBundleDependency() - .setRequired(true) - .setFilter("(Bundle-SymbolicName=" + BSN + ")") - .setCallbacks("add", "remove") - ); + // add a consumer with a filter + FilteredConsumerRequiredWithComponentArg impl = new FilteredConsumerRequiredWithComponentArg(e); + Component consumerWithFilter = component(m, c -> c.impl(impl) + .withBundle(b -> b.filter("(Bundle-SymbolicName=" + BSN + ")").cb("add", "remove"))); + e.waitForStep(1, 5000); + // remove the consumer again + m.remove(consumerWithFilter); + e.waitForStep(2, 5000); + } + + public void testRequiredBundleDependencyWithComponentArgInCallbackMethodRef() { + DependencyManager m = getDM(); + + // helper class that ensures certain steps get executed in sequence + Ensure e = new Ensure(); + FilteredConsumerRequiredWithComponentArg impl = new FilteredConsumerRequiredWithComponentArg(e); + Component consumerWithFilter = component(m, c -> c + .autoAdd(false).impl(impl) + .withBundle(b -> b.filter("(Bundle-SymbolicName=" + BSN + ")").cb(impl::add, impl::remove))); // add a consumer with a filter m.add(consumerWithFilter); e.waitForStep(1, 5000); @@ -159,19 +201,26 @@ public class BundleDependencyTest extend } } - static class FilteredConsumerRequiredWithComponentArg extends FilteredConsumerRequired { + static class FilteredConsumerRequiredWithComponentArg { + private final Ensure m_ensure; + public FilteredConsumerRequiredWithComponentArg(Ensure e) { - super(e); + m_ensure = e; } - + public void add(Component component, Bundle b) { Assert.assertNotNull(component); - super.add(b); + if (b.getSymbolicName().equals(BSN)) { + m_ensure.step(1); + } } public void remove(Component component, Bundle b) { Assert.assertNotNull(component); - super.remove(b); + Assert.assertNotNull(b); + if (b.getSymbolicName().equals(BSN)) { + m_ensure.step(2); + } } } } Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ComponentTest.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/ComponentTest.java?rev=1724333&r1=1724332&r2=1724333&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ComponentTest.java (original) +++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ComponentTest.java Tue Jan 12 22:45:36 2016 @@ -18,9 +18,11 @@ */ 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.CB.REM; import static org.apache.felix.dm.builder.lambda.DependencyActivatorBase.component; -import java.util.Map; +import java.util.Dictionary; import org.apache.felix.dm.DependencyManager; import org.junit.Assert; @@ -34,12 +36,10 @@ public class ComponentTest extends TestB public void testSimple() throws Exception { final DependencyManager dm = getDM(); - java.util.function.Consumer<Provider> cons = (p) -> System.out.println("Injected provider: " + p); - // Create consumer (dependency is required by default using builder api). component(dm, comp -> comp .factory(Consumer::new) - .withService(Provider.class, srv -> srv.filter("(name=provider2)").onAdd(cons::accept).onAdd(Consumer::add).onRemove(Consumer::remove)) + .withService(Provider.class, srv -> srv.filter("(name=provider2)").cb(ADD, Consumer::add).cb(REM, Consumer::remove)) .withService(Provider.class, srv -> srv.filter("(name=provider1)").autoConfig("m_autoConfiguredProvider"))); // Create providers (auto added to dependency manager) @@ -62,9 +62,8 @@ public class ComponentTest extends TestB public class Consumer { Provider m_provider; Provider m_autoConfiguredProvider; - - @SuppressWarnings("rawtypes") - void add(Provider provider, Map props) { + + void add(Provider provider, Dictionary<String, Object> props) { Assert.assertNotNull(provider); Assert.assertEquals("provider2", props.get("name")); m_provider = provider; @@ -85,7 +84,7 @@ public class ComponentTest extends TestB m_ensure.step(4); } - void remove(Provider provider) { + void remove(Provider provider, Dictionary<String, Object> props) { Assert.assertEquals(m_provider, provider); m_ensure.step(5); } Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ModifiedBundleDependencyTest.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/ModifiedBundleDependencyTest.java?rev=1724333&view=auto ============================================================================== --- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ModifiedBundleDependencyTest.java (added) +++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ModifiedBundleDependencyTest.java Tue Jan 12 22:45:36 2016 @@ -0,0 +1,169 @@ +/* + * 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; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleException; + +/** + * Test for FELIX-4334 issue. + * + * Two components: A, B + * + * - A provided. + * - B has a bundle dependency on the dependency manager shell bundle, which is currently stopped. + * - B has an instance bound dependency on A. + * - Now unregister A. + * - As a result of that, B becomes unavailable and is unbound from A. But B is not destroyed, because A dependency + * is "instance bound". So B is still bound to the bundle dependency. + * - Now, someone starts the dependency manager shell bundle: B then shall be called in its "changed" callback. + * + * @author <a href="mailto:[email protected]">Felix Project Team</a> + */ +public class ModifiedBundleDependencyTest extends TestBase { + public static interface A { + } + + static class AImpl implements A { + } + + public static interface B { + } + + static class BImpl implements B { + final Ensure m_e; + + BImpl(Ensure e) { + m_e = e; + } + + public void add(Bundle dmTest) { + m_e.step(1); + } + + void init(Component c) { + m_e.step(2); + component(c, comp -> comp.withService(A.class, srv -> srv.cb("add", "remove"))); + } + + public void add(A a) { + m_e.step(3); + } + + public void start() { + m_e.step(4); + } + + public void stop() { + m_e.step(5); + } + + public void remove(A a) { + m_e.step(6); + } + + public void change(Bundle dmTest) { // called two times: one for STARTING, one for STARTED + m_e.step(); + } + + public void destroy() { + m_e.step(9); + } + + public void remove(Bundle dmTest) { + m_e.step(10); + } + } + + public void testAdapterWithChangedInstanceBoundDependencyAndCallbacks() { + DependencyManager m = getDM(); + Ensure e = new Ensure(); + + Component a = + component(m, comp -> comp.impl(new AImpl()).provides(A.class).autoAdd(false)); + + String filter = "(Bundle-SymbolicName=org.apache.felix.metatype)"; + int mask = Bundle.INSTALLED|Bundle.ACTIVE|Bundle.RESOLVED|Bundle.STARTING; + Component b = component(m, comp -> comp.provides(B.class).impl(new BImpl(e)).autoAdd(false) + .withBundle(bundle -> bundle.filter(filter).mask(mask).cb("add", "change", "remove"))); + + Bundle dmtest = getBundle("org.apache.felix.metatype"); + try { + dmtest.stop(); + } catch (BundleException e1) { + Assert.fail("could not find metatype bundle"); + } + + m.add(a); + m.add(b); + + e.waitForStep(4, 5000); + m.remove(a); // B will loose A and will enter into "waiting for required (instantiated)" state. + System.out.println("Starting metatype bundle ..."); + try { + dmtest.start(); + } catch (BundleException e1) { + Assert.fail("could not start metatype bundle"); + } + e.waitForStep(7, 5000); + m.remove(b); + e.waitForStep(10, 5000); + } + + public void testAdapterWithChangedInstanceBoundDependencyRef() { + DependencyManager m = getDM(); + Ensure e = new Ensure(); + + Component a = + component(m, comp -> comp.impl(new AImpl()).provides(A.class).autoAdd(false)); + + BImpl impl = new BImpl(e); + String filter = "(Bundle-SymbolicName=org.apache.felix.metatype)"; + int mask = Bundle.INSTALLED|Bundle.ACTIVE|Bundle.RESOLVED|Bundle.STARTING; + Component b = component(m, comp -> comp.provides(B.class).impl(impl).autoAdd(false) + .withBundle(bundle -> bundle.filter(filter).mask(mask).cb(impl::add, impl::change, impl::remove))); + + Bundle dmtest = getBundle("org.apache.felix.metatype"); + try { + dmtest.stop(); + } catch (BundleException e1) { + Assert.fail("could not find metatype bundle"); + } + + m.add(a); + m.add(b); + + e.waitForStep(4, 5000); + m.remove(a); // B will loose A and will enter into "waiting for required (instantiated)" state. + System.out.println("Starting metatype bundle ..."); + try { + dmtest.start(); + } catch (BundleException e1) { + Assert.fail("could not start metatype bundle"); + } + e.waitForStep(7, 5000); + m.remove(b); + e.waitForStep(10, 5000); + } +} Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ResourceProvider.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/ResourceProvider.java?rev=1724333&r1=1724332&r2=1724333&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ResourceProvider.java (original) +++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ResourceProvider.java Tue Jan 12 22:45:36 2016 @@ -23,9 +23,9 @@ import java.util.Dictionary; import java.util.HashMap; import java.util.Map; -import org.junit.Assert; import org.apache.felix.dm.ResourceHandler; import org.apache.felix.dm.ResourceUtil; +import org.junit.Assert; import org.osgi.framework.BundleContext; import org.osgi.framework.Filter; import org.osgi.framework.InvalidSyntaxException; @@ -66,7 +66,7 @@ class ResourceProvider { } @SuppressWarnings({ "deprecation", "unchecked" }) - public void add(ResourceHandler handler, ServiceReference<ResourceHandler> ref) { + public void add(ServiceReference<ResourceHandler> ref, ResourceHandler handler) { String filterString = (String) ref.getProperty("filter"); Filter filter = null; if (filterString != null) { @@ -88,7 +88,7 @@ class ResourceProvider { } } - public void remove(ResourceHandler handler, ServiceReference<ResourceHandler> ref) { + public void remove(ServiceReference<ResourceHandler> ref, ResourceHandler handler) { Filter filter; synchronized (m_handlers) { filter = (Filter) m_handlers.remove(handler); Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceDependencyTest.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/ServiceDependencyTest.java?rev=1724333&r1=1724332&r2=1724333&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceDependencyTest.java (original) +++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceDependencyTest.java Tue Jan 12 22:45:36 2016 @@ -18,6 +18,8 @@ */ 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.CB.REM; import static org.apache.felix.dm.builder.lambda.DependencyActivatorBase.component; import org.apache.felix.dm.Component; @@ -36,7 +38,7 @@ public class ServiceDependencyTest exten Component sc = component(m, comp -> comp.autoAdd(false).impl(new ServiceConsumer(e)).withService(ServiceInterface.class)); Component sc2 = component(m, comp -> comp.autoAdd(false).impl(new ServiceConsumerCallbacks(e)) - .withService(ServiceInterface.class, srv -> srv.required(false).onAdd(ServiceConsumerCallbacks::add).onRemove(ServiceConsumerCallbacks::remove))); + .withService(ServiceInterface.class, srv -> srv.required(false).cb(ADD, ServiceConsumerCallbacks::add).cb(REM, ServiceConsumerCallbacks::remove))); m.add(sp); m.add(sc); Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceDependencyThroughCallbackInstanceTest.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/ServiceDependencyThroughCallbackInstanceTest.java?rev=1724333&r1=1724332&r2=1724333&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceDependencyThroughCallbackInstanceTest.java (original) +++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceDependencyThroughCallbackInstanceTest.java Tue Jan 12 22:45:36 2016 @@ -18,11 +18,12 @@ */ package org.apache.felix.dm.builder.lambda.itest; -import org.junit.Assert; - +import static org.apache.felix.dm.builder.lambda.CB.ADD; +import static org.apache.felix.dm.builder.lambda.CB.REM; import static org.apache.felix.dm.builder.lambda.DependencyActivatorBase.component; import org.apache.felix.dm.DependencyManager; +import org.junit.Assert; import org.osgi.framework.BundleContext; /** @@ -53,7 +54,7 @@ public class ServiceDependencyThroughCal CallbackInstance instance = new CallbackInstance(); component(m, comp -> comp .impl(new SimpleService() {}) - .withService(Service.class, srv -> srv.onAdd(instance::added).onRemove(instance::removed))); + .withService(Service.class, srv -> srv.cbi(ADD, instance::added).cbi(REM, instance::removed))); Assert.assertEquals(numberOfServices, instance.getCount()); m.clear(); Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceUpdateTest.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/ServiceUpdateTest.java?rev=1724333&r1=1724332&r2=1724333&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceUpdateTest.java (original) +++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceUpdateTest.java Tue Jan 12 22:45:36 2016 @@ -18,6 +18,9 @@ */ 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.CB.CHG; +import static org.apache.felix.dm.builder.lambda.CB.REM; import static org.apache.felix.dm.builder.lambda.DependencyActivatorBase.component; import java.net.URL; @@ -44,10 +47,10 @@ public class ServiceUpdateTest extends T component(m, comp -> comp .impl(new ServiceProvider(e)) .withService(ServiceInterface.class, srv -> srv - .onAdd(ServiceProvider::add).onChange(ServiceProvider::change).onRemove(ServiceProvider::remove))); + .cb(ADD, ServiceProvider::add).cb(CHG, ServiceProvider::change).cb(REM, ServiceProvider::remove))); component(m, comp -> comp .impl(provider) - .withService(ResourceHandler.class, srv -> srv.onAdd(ResourceProvider::add).onRemove(ResourceProvider::remove))); + .withService(ResourceHandler.class, srv -> srv.cb(ADD, ResourceProvider::add).cb(REM, ResourceProvider::remove))); // TODO implement resource adapters in new builder API and use it for the following resource adapter. Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceUtil.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/ServiceUtil.java?rev=1724333&r1=1724332&r2=1724333&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceUtil.java (original) +++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceUtil.java Tue Jan 12 22:45:36 2016 @@ -39,7 +39,7 @@ public class ServiceUtil { * @param ref the service reference to determine the ranking for * @return the ranking */ - public static int getRanking(ServiceReference ref) { + public static int getRanking(ServiceReference<?> ref) { return getRankingAsInteger(ref).intValue(); } @@ -51,7 +51,7 @@ public class ServiceUtil { * @param ref the service reference to determine the ranking for * @return the ranking */ - public static Integer getRankingAsInteger(ServiceReference ref) { + public static Integer getRankingAsInteger(ServiceReference<?> ref) { Integer rank = (Integer) ref.getProperty(Constants.SERVICE_RANKING); if (rank != null) { return rank; @@ -67,7 +67,7 @@ public class ServiceUtil { * @param ref the service reference to determine the service ID of * @return the service ID */ - public static long getServiceId(ServiceReference ref) { + public static long getServiceId(ServiceReference<?> ref) { return getServiceIdAsLong(ref).longValue(); } @@ -79,11 +79,11 @@ public class ServiceUtil { * @param ref the service reference to determine the service ID of * @return the service ID */ - public static Long getServiceIdAsLong(ServiceReference ref) { + public static Long getServiceIdAsLong(ServiceReference<?> ref) { return getServiceIdObject(ref); } - public static Long getServiceIdObject(ServiceReference ref) { + public static Long getServiceIdObject(ServiceReference<?> ref) { Long aid = (Long) ref.getProperty(DependencyManager.ASPECT); if (aid != null) { return aid; @@ -102,7 +102,7 @@ public class ServiceUtil { * @param ref the service reference * @return <code>true</code> if it's an aspect, <code>false</code> otherwise */ - public static boolean isAspect(ServiceReference ref) { + public static boolean isAspect(ServiceReference<?> ref) { Long aid = (Long) ref.getProperty(DependencyManager.ASPECT); return (aid != null); } @@ -114,7 +114,7 @@ public class ServiceUtil { * @param ref the service reference * @return a string representation of the service */ - public static String toString(ServiceReference ref) { + public static String toString(ServiceReference<?> ref) { if (ref == null) { return "ServiceReference[null]"; } @@ -142,7 +142,7 @@ public class ServiceUtil { * @param exclude a list of properties to exclude, or <code>null</code> to show everything * @return a string representation of the service properties */ - public static String propertiesToString(ServiceReference ref, List<String> exclude) { + public static String propertiesToString(ServiceReference<?> ref, List<String> exclude) { StringBuffer buf = new StringBuffer(); String[] keys = ref.getPropertyKeys(); for (int i = 0; i < keys.length; i++) { Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/TestBase.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/TestBase.java?rev=1724333&r1=1724332&r2=1724333&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/TestBase.java (original) +++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/TestBase.java Tue Jan 12 22:45:36 2016 @@ -26,12 +26,10 @@ import java.util.concurrent.ExecutorServ import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; -import org.junit.Assert; -import junit.framework.TestCase; - import org.apache.felix.dm.Component; import org.apache.felix.dm.ComponentExecutorFactory; import org.apache.felix.dm.DependencyManager; +import org.junit.Assert; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleException; @@ -43,6 +41,8 @@ import org.osgi.framework.ServiceReferen import org.osgi.framework.ServiceRegistration; import org.osgi.service.log.LogService; +import junit.framework.TestCase; + /** * Base class for all integration tests. * Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/compositefactory/Activator.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/compositefactory/Activator.java?rev=1724333&r1=1724332&r2=1724333&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/compositefactory/Activator.java (original) +++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/compositefactory/Activator.java Tue Jan 12 22:45:36 2016 @@ -19,14 +19,22 @@ package org.apache.felix.dependencymanager.lambda.samples.compositefactory; import static java.lang.System.out; +import static org.apache.felix.dm.builder.lambda.CB.ADD; import org.apache.felix.dm.builder.lambda.DependencyActivatorBase; import org.osgi.service.cm.ConfigurationAdmin; import org.osgi.service.log.LogService; /** - * Defines a factory that also returns a composition. - * The LogService in only injected to the ProviderImpl and the ProviderParticipant1. + * Creates a "Provider" service. The implementation for this service (ProviderImpl) is + * created using a factory class (ProviderFactory) that also creates some other helper classes + * (ProviderComposite1 and ProviderComposite2) that are internally used by ProviderImpl. + * + * The ProviderFactory is also injected with a Configuration that can be used by the Factory + * when creating the ProviderImpl, ProviderComposite1, and ProviderComposite2 classes. + * + * The LogService in only injected to the ProviderImpl and the ProviderComposite1 classes. + * Both composites are called in their "start" callbacks, when all required dependencies are available. * * @author <a href="mailto:[email protected]">Felix Project Team</a> */ @@ -35,14 +43,21 @@ public class Activator extends Dependenc public void init() throws Exception { out.println("type \"log info\" to see the logs emitted by this test."); - CompositionManager compositionMngr = new CompositionManager(); - + // Create the Factory used to instantiate ProvuderImpl, ProviderComposite1 and ProviderComposite2 + ProviderFactory factory = new ProviderFactory(); + + // Define the component which implementation is instantiated by the ProviderFactory. + // a LogService is injected in the ProviderImpl, as well as to the ProviderComposite1 class. + // And a configuration is injected directly to the ProviderFactory so it can use some configurations + // before creating the composition of classes. component(comp -> comp - .factory(compositionMngr::create, compositionMngr::getComposition) - .withService(LogService.class, srv -> srv.onAdd(ProviderImpl::bind).onAdd(ProviderParticipant1::bind)) - .withConfiguration(conf -> conf.pid(CompositionManager.class).onUpdate(compositionMngr::updated))); + .factory(factory::create, factory::getComposition) + .withService(LogService.class, srv -> srv.cb(ADD, ProviderImpl::bind).cb(ADD, ProviderComposite1::bind)) + .withConfiguration(conf -> conf.pid(ProviderFactory.class).cb(factory::updated))); + // Creates a configuration with pid name = "org.apache.felix.dependencymanager.lambda.samples.compositefactory.ProviderFactory" component(comp -> comp - .impl(Configurator.class).withService(ConfigurationAdmin.class)); + .impl(Configurator.class) + .withService(ConfigurationAdmin.class)); } } Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/compositefactory/Configurator.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/compositefactory/Configurator.java?rev=1724333&r1=1724332&r2=1724333&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/compositefactory/Configurator.java (original) +++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/compositefactory/Configurator.java Tue Jan 12 22:45:36 2016 @@ -12,7 +12,7 @@ public class Configurator { void start() throws IOException { // Configure the ServiceConsumer component - Configuration c = m_cm.getConfiguration(CompositionManager.class.getName(), null); + Configuration c = m_cm.getConfiguration(ProviderFactory.class.getName(), null); Dictionary<String, Object> props = new Hashtable<>(); props.put("foo", "bar"); c.update(props); Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/compositefactory/ProviderComposite1.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/compositefactory/ProviderComposite1.java?rev=1724333&view=auto ============================================================================== --- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/compositefactory/ProviderComposite1.java (added) +++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/compositefactory/ProviderComposite1.java Tue Jan 12 22:45:36 2016 @@ -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.felix.dependencymanager.lambda.samples.compositefactory; + +import org.osgi.service.log.LogService; + +/** + * @author <a href="mailto:[email protected]">Felix Project Team</a> + */ +public class ProviderComposite1 { + private volatile LogService m_log; + + public void bind(LogService log) { + m_log = log; + } + + void start() { + m_log.log(LogService.LOG_INFO, "ProviderParticipant1.start()"); + } +} Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/compositefactory/ProviderComposite2.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/compositefactory/ProviderComposite2.java?rev=1724333&view=auto ============================================================================== --- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/compositefactory/ProviderComposite2.java (added) +++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/compositefactory/ProviderComposite2.java Tue Jan 12 22:45:36 2016 @@ -0,0 +1,26 @@ +/* + * 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.dependencymanager.lambda.samples.compositefactory; + +/** + * @author <a href="mailto:[email protected]">Felix Project Team</a> + */ +public class ProviderComposite2 { + +} Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/compositefactory/ProviderFactory.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/compositefactory/ProviderFactory.java?rev=1724333&view=auto ============================================================================== --- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/compositefactory/ProviderFactory.java (added) +++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/compositefactory/ProviderFactory.java Tue Jan 12 22:45:36 2016 @@ -0,0 +1,62 @@ +/* + * 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.dependencymanager.lambda.samples.compositefactory; + +import java.util.Dictionary; + +/** + * Pojo used to create all the objects composition used to implements the "Provider" Service. + * The manager is using a Configuration injected by Config Admin, in order to configure the + * various objects being part of the "Provider" service implementation. + * + * @author <a href="mailto:[email protected]">Felix Project Team</a> + */ +public class ProviderFactory { + private ProviderComposite1 m_composite1; + private ProviderComposite2 m_composite2; + private ProviderImpl m_providerImpl; + @SuppressWarnings("unused") + private Dictionary<String, Object> m_conf; + + public void updated(Dictionary<String, Object> conf) { + // validate configuration and throw an exception if the properties are invalid + m_conf = conf; + } + + /** + * Builds the composition of objects used to implement the "Provider" service. + * The Configuration injected by Config Admin will be used to configure the components + * @return The "main" object providing the "Provider" service. + */ + ProviderImpl create() { + // Here, we can instantiate our object composition and configure them using the injected Configuration ... + m_composite1 = new ProviderComposite1(); // possibly configure this object using our configuration + m_composite2 = new ProviderComposite2(); // possibly configure this object using our configuration + m_providerImpl = new ProviderImpl(m_composite1, m_composite2); + return m_providerImpl; // Main object implementing the Provider service + } + + /** + * Returns the + * @return + */ + Object[] getComposition() { + return new Object[] { m_providerImpl, m_composite1, m_composite2 }; + } +} Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/compositefactory/ProviderImpl.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/compositefactory/ProviderImpl.java?rev=1724333&r1=1724332&r2=1724333&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/compositefactory/ProviderImpl.java (original) +++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/compositefactory/ProviderImpl.java Tue Jan 12 22:45:36 2016 @@ -30,15 +30,15 @@ import org.osgi.service.log.LogService; * @author <a href="mailto:[email protected]">Felix Project Team</a> */ public class ProviderImpl implements Provider { - private final ProviderParticipant1 m_participant1; - private final ProviderParticipant2 m_participant2; + private final ProviderComposite1 m_participant1; + private final ProviderComposite2 m_participant2; private volatile LogService m_log; public void bind(LogService log) { m_log = log; } - ProviderImpl(ProviderParticipant1 participant1, ProviderParticipant2 participant2) { + ProviderImpl(ProviderComposite1 participant1, ProviderComposite2 participant2) { m_participant1 = participant1; m_participant2 = participant2; } Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/device/Activator.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/device/Activator.java?rev=1724333&r1=1724332&r2=1724333&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/device/Activator.java (original) +++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/device/Activator.java Tue Jan 12 22:45:36 2016 @@ -19,6 +19,7 @@ package org.apache.felix.dependencymanager.lambda.samples.device; import static java.lang.System.out; +import static org.apache.felix.dm.builder.lambda.CB.ADD; import org.apache.felix.dm.builder.lambda.DependencyActivatorBase; import org.osgi.service.log.LogService; @@ -34,21 +35,22 @@ public class Activator extends Dependenc createDeviceAndParameter(1); createDeviceAndParameter(2); - adapter(Device.class, comp -> comp.provides(DeviceAccess.class).impl(DeviceAccessImpl.class)); + adapter(Device.class, comp -> comp + .provides(DeviceAccess.class).impl(DeviceAccessImpl.class)); component(comp -> comp .impl(DeviceAccessConsumer.class) .withService(LogService.class) - .withService(DeviceAccess.class, srv -> srv.onAdd(DeviceAccessConsumer::add))); + .withService(DeviceAccess.class, srv -> srv.cb(ADD, DeviceAccessConsumer::add))); } private void createDeviceAndParameter(int id) { component(buicomplder -> buicomplder - .provides(Device.class).properties("device.id", id) - .factory(() -> new DeviceImpl(id))); + .factory(() -> new DeviceImpl(id)) + .provides(Device.class).properties("device.id", id)); component(comp -> comp - .provides(DeviceParameter.class).properties("device.id", id) - .factory(() -> new DeviceParameterImpl(id))); + .factory(() -> new DeviceParameterImpl(id)) + .provides(DeviceParameter.class).properties("device.id", id)); } } Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/dictionary/Activator.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/dictionary/Activator.java?rev=1724333&r1=1724332&r2=1724333&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/dictionary/Activator.java (original) +++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/dictionary/Activator.java Tue Jan 12 22:45:36 2016 @@ -34,23 +34,26 @@ public class Activator extends Dependenc out.println("type \"log info\" to see the logs emitted by this test."); // Create the factory configuration for our DictionaryImpl service. - factoryPidAdapter(comp -> comp - .factoryPid(DictionaryConfiguration.class).onUpdate(DictionaryImpl::updated).propagate() - .provides(DictionaryService.class) + factoryPidAdapter(adapter -> adapter .impl(DictionaryImpl.class) + .factoryPid(DictionaryConfiguration.class) + .cb(DictionaryImpl::updated) + .propagate() + .provides(DictionaryService.class) .withService(LogService.class, dep -> dep.required(false))); // Create the Dictionary Aspect - aspect(DictionaryService.class, asp -> asp - .filter("(lang=en)").rank(10).impl(DictionaryAspect.class) - .withConfiguration(conf -> conf.pid(DictionaryAspectConfiguration.class).onUpdate(DictionaryAspect::addWords)) + aspect(DictionaryService.class, aspect -> aspect + .impl(DictionaryAspect.class) + .filter("(lang=en)").rank(10) + .withConfiguration(conf -> conf.pid(DictionaryAspectConfiguration.class).cb(DictionaryAspect::addWords)) .withService(LogService.class, srv -> srv.required(false))); // Create the SpellChecker component component(comp -> comp - .provides(SpellChecker.class) - .properties(COMMAND_SCOPE, "dictionary", COMMAND_FUNCTION, new String[] {"spellcheck"}) .impl(SpellChecker.class) + .provides(SpellChecker.class) + .properties(COMMAND_SCOPE, "dictionary", COMMAND_FUNCTION, new String[] {"spellcheck"}) .withService(DictionaryService.class, srv -> srv.required()) .withService(LogService.class, srv -> srv.required(false))); } Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/factory/Activator.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/factory/Activator.java?rev=1724333&r1=1724332&r2=1724333&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/factory/Activator.java (original) +++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/factory/Activator.java Tue Jan 12 22:45:36 2016 @@ -19,6 +19,7 @@ package org.apache.felix.dependencymanager.lambda.samples.factory; import static java.lang.System.out; +import static org.apache.felix.dm.builder.lambda.CB.ADD; import org.apache.felix.dm.builder.lambda.DependencyActivatorBase; import org.osgi.service.log.LogService; @@ -32,9 +33,9 @@ public class Activator extends Dependenc out.println("type \"log info\" to see the logs emitted by this test."); component(comp -> comp - .provides(Provider.class) .factory(ProviderFactory::new, ProviderFactory::create) - .withService(LogService.class, srv -> srv.required().onAdd(ProviderImpl::set)) - .onStart(ProviderImpl::start)); + .provides(Provider.class) + .start(ProviderImpl::start) + .withService(LogService.class, srv -> srv.required().cb(ADD, ProviderImpl::set))); } } Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/factory/ProviderFactory.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/factory/ProviderFactory.java?rev=1724333&r1=1724332&r2=1724333&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/factory/ProviderFactory.java (original) +++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/factory/ProviderFactory.java Tue Jan 12 22:45:36 2016 @@ -1,7 +1,7 @@ package org.apache.felix.dependencymanager.lambda.samples.factory; public class ProviderFactory { - public Object create() { + public ProviderImpl create() { return new ProviderImpl(); } }
