You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ui...@apache.org on 2014/05/19 08:47:08 UTC
svn commit: r1595756 [1/2] - in
/felix/sandbox/pderop/dependencymanager-prototype: dm.it/src/dm/it/
dm/src/dm/ dm/src/dm/impl/ dm/src/dm/impl/index/
dm/src/dm/impl/index/multiproperty/ dm/src/dm/impl/metatype/ dm/src/tracker/
Author: uiterlix
Date: Mon May 19 06:47:07 2014
New Revision: 1595756
URL: http://svn.apache.org/r1595756
Log:
Work in progress on Aspects. Yet to resolve issues especially in Aspects and concurrency.
Added:
felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectBaseTest.java (with props)
felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectChainTest.java (with props)
felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectDynamicsTest.java (with props)
felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectRaceTest.java (with props)
felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectServiceDependencyWithSwapCallbackTest.java (with props)
felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectWhiteboardTest.java (with props)
felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectWithCallbacksServiceDependencyTest.java (with props)
felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectWithPropagationTest.java (with props)
felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/AspectServiceImpl.java (with props)
Modified:
felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectServiceDependencyTest.java
felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/Component.java
felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/DependencyActivatorBase.java
felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/DependencyManager.java
felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/ServiceDependency.java
felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/AbstractDecorator.java
felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/ComponentImpl.java
felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/DependencyImpl.java
felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/FactoryConfigurationAdapterImpl.java
felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/FilterComponent.java
felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/Logger.java
felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/SerialExecutor.java
felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/ServiceDependencyImpl.java
felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/TemporalServiceDependencyImpl.java
felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/index/AspectFilterIndex.java
felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/index/ServiceRegistryCache.java
felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/index/multiproperty/Property.java
felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/metatype/MetaTypeProviderImpl.java
felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/metatype/PropertyMetaDataImpl.java
felix/sandbox/pderop/dependencymanager-prototype/dm/src/tracker/AbstractTracked.java
felix/sandbox/pderop/dependencymanager-prototype/dm/src/tracker/ServiceTracker.java
Added: felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectBaseTest.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectBaseTest.java?rev=1595756&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectBaseTest.java (added)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectBaseTest.java Mon May 19 06:47:07 2014
@@ -0,0 +1,198 @@
+package dm.it;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import junit.framework.Assert;
+
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+import dm.Component;
+import dm.DependencyManager;
+
+public class AspectBaseTest extends TestBase {
+
+ public void testSingleAspect() {
+ DependencyManager m = new DependencyManager(context);
+ // helper class that ensures certain steps get executed in sequence
+ Ensure e = new Ensure();
+
+ // create a service provider and consumer
+ ServiceProvider p = new ServiceProvider(e, "a");
+ ServiceConsumer c = new ServiceConsumer(e);
+ Component sp = m.createComponent()
+ .setInterface(ServiceInterface.class.getName(), new Properties() {{ put("name", "a"); }})
+ .setImplementation(p);
+ Component sc = m.createComponent()
+ .setImplementation(c)
+ .add(m.createServiceDependency()
+ .setService(ServiceInterface.class)
+ .setRequired(true)
+ .setCallbacks("add", "remove")
+ .setAutoConfig(true)
+ );
+ Component sa = m.createAspectService(ServiceInterface.class, null, 20, null)
+ .setImplementation(ServiceAspect.class);
+ m.add(sc);
+ m.add(sp);
+ // after the provider was added, the consumer's add should have been invoked once
+ e.waitForStep(1, 2000);
+ Assert.assertEquals("a", c.invoke());
+ m.add(sa);
+ // after the aspect was added, the consumer should get and add for the aspect and a remove
+ // for the original service
+ e.waitForStep(3, 2000);
+ Assert.assertEquals("aa", c.invoke());
+ m.remove(sa);
+ // removing the aspect again should give a remove and add
+ e.waitForStep(5, 2000);
+ Assert.assertEquals("a", c.invoke());
+ m.remove(sp);
+ // finally removing the original service should give a remove
+ e.waitForStep(6, 2000);
+ m.remove(sc);
+ e.step(7);
+ }
+
+ public void testSingleAspectThatAlreadyExisted() {
+ DependencyManager m = new DependencyManager(context);
+ // helper class that ensures certain steps get executed in sequence
+ Ensure e = new Ensure();
+
+ // create a service provider and consumer
+ ServiceProvider p = new ServiceProvider(e, "a");
+ ServiceConsumer c = new ServiceConsumer(e);
+ Component sp = m.createComponent().setImplementation(p).setInterface(ServiceInterface.class.getName(), new Properties() {{ put("name", "a"); }});
+ Component sc = m.createComponent().setImplementation(c).add(m.createServiceDependency().setService(ServiceInterface.class).setRequired(true).setCallbacks("add", "remove").setAutoConfig(true));
+ Component sa = m.createAspectService(ServiceInterface.class, null, 20, null).setImplementation(ServiceAspect.class);
+ // we first add the aspect
+ m.add(sa);
+ // then the service provider
+ m.add(sp);
+ // finally the consumer
+ m.add(sc);
+
+ Assert.assertEquals("aa", c.invoke());
+
+ // now the consumer's added should be invoked once, as the aspect is already available and should
+ // directly hide the original service
+ e.waitForStep(1, 2000);
+ e.step(2);
+
+ m.remove(sa);
+ // after removing the aspect, the consumer should get the original service back, so
+ // remove and add will be invoked
+ e.waitForStep(4, 2000);
+
+ Assert.assertEquals("a", c.invoke());
+
+ m.remove(sp);
+ // after removing the original service, the consumer's remove should be called once
+ e.waitForStep(5, 2000);
+
+ m.remove(sc);
+ e.step(6);
+ }
+
+ public void testMultipleAspects() {
+ DependencyManager m = new DependencyManager(context);
+ // helper class that ensures certain steps get executed in sequence
+ Ensure e = new Ensure();
+
+ // create service providers and consumers
+ ServiceConsumer c = new ServiceConsumer(e);
+ Component sp = m.createComponent().setImplementation(new ServiceProvider(e, "a")).setInterface(ServiceInterface.class.getName(), new Properties() {{ put("name", "a"); }});
+ Component sp2 = m.createComponent().setImplementation(new ServiceProvider(e, "b")).setInterface(ServiceInterface.class.getName(), new Properties() {{ put("name", "b"); }});
+ Component sc = m.createComponent().setImplementation(c).add(m.createServiceDependency().setService(ServiceInterface.class).setRequired(true).setCallbacks("add", "remove"));
+ Component sa = m.createAspectService(ServiceInterface.class, null, 20, null).setImplementation(ServiceAspect.class);
+ Component sa2 = m.createAspectService(ServiceInterface.class, null, 10, null).setImplementation(ServiceAspect.class);
+ m.add(sp);
+ m.add(sp2);
+ m.add(sa);
+ m.add(sa2);
+ m.add(sc);
+ // the consumer will monitor progress, it should get it's add invoked twice, once for every
+ // (highest) aspect
+ e.waitForStep(2, 2000);
+ e.step(3);
+
+ // now invoke all services the consumer collected
+ List<String> list = c.invokeAll();
+ // and make sure both of them are correctly invoked
+ Assert.assertTrue(list.size() == 2);
+ Assert.assertTrue(list.contains("aaa"));
+ Assert.assertTrue(list.contains("bbb"));
+
+ m.remove(sc);
+ // removing the consumer now should get its removed method invoked twice
+ e.waitForStep(5, 2000);
+ e.step(6);
+ m.remove(sa2);
+ m.remove(sa);
+ m.remove(sp2);
+ m.remove(sp);
+ e.step(7);
+ }
+
+ public static interface ServiceInterface {
+ public String invoke(String input);
+ }
+
+ public static class ServiceProvider implements ServiceInterface {
+ private final Ensure m_ensure;
+ private final String m_name;
+ public ServiceProvider(Ensure e, String name) {
+ m_ensure = e;
+ m_name = name;
+ }
+ public String invoke(String input) {
+ return input + m_name;
+ }
+ }
+
+ public static class ServiceAspect implements ServiceInterface {
+ private volatile ServiceInterface m_originalService;
+ private volatile ServiceRegistration m_registration;
+
+ public String invoke(String input) {
+ String result = m_originalService.invoke(input);
+ String property = (String) m_registration.getReference().getProperty("name");
+ return result + property;
+ }
+ }
+
+ public static class ServiceConsumer {
+ private final Ensure m_ensure;
+ private volatile ServiceInterface m_service;
+ private List<ServiceInterface> m_services = new ArrayList<ServiceInterface>();
+
+ public ServiceConsumer(Ensure e) {
+ m_ensure = e;
+ }
+
+ public void add(ServiceReference ref, ServiceInterface si) {
+ System.out.println("add: " + ServiceUtil.toString(ref));
+ m_services.add(si);
+ m_ensure.step();
+ }
+
+ public void remove(ServiceReference ref, ServiceInterface si) {
+ System.out.println("rem: " + ServiceUtil.toString(ref));
+ m_services.remove(si);
+ m_ensure.step();
+ }
+
+ public String invoke() {
+ return m_service.invoke("");
+ }
+
+ public List<String> invokeAll() {
+ List<String> results = new ArrayList<String>();
+ for (ServiceInterface si : m_services) {
+ results.add(si.invoke(""));
+ }
+ return results;
+ }
+ }
+}
Propchange: felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectBaseTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectChainTest.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectChainTest.java?rev=1595756&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectChainTest.java (added)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectChainTest.java Mon May 19 06:47:07 2014
@@ -0,0 +1,86 @@
+package dm.it;
+import dm.Component;
+import dm.DependencyManager;
+
+public class AspectChainTest extends TestBase {
+
+ public void testBuildAspectChain() {
+ DependencyManager m = new DependencyManager(context);
+ // helper class that ensures certain steps get executed in sequence
+ Ensure e = new Ensure();
+ // create a service provider and consumer
+ Component sp = m.createComponent().setImplementation(new ServiceProvider(e)).setInterface(ServiceInterface.class.getName(), null);
+ Component sc = m.createComponent().setImplementation(new ServiceConsumer(e)).add(m.createServiceDependency().setService(ServiceInterface.class).setRequired(true));
+ Component sa2 = m.createAspectService(ServiceInterface.class, null, 20, null).setImplementation(new ServiceAspect(e, 3));
+ Component sa3 = m.createAspectService(ServiceInterface.class, null, 30, null).setImplementation(new ServiceAspect(e, 2));
+ Component sa1 = m.createAspectService(ServiceInterface.class, null, 10, null).setImplementation(new ServiceAspect(e, 4));
+ m.add(sc);
+
+ m.add(sp);
+ m.add(sa2);
+ m.add(sa3);
+ m.add(sa1);
+ e.step();
+
+ m.remove(sa3);
+ m.remove(sa2);
+ m.remove(sa1);
+ m.remove(sp);
+
+ m.remove(sc);
+ }
+
+ static interface ServiceInterface {
+ public void invoke(Runnable run);
+ }
+
+ static class ServiceProvider implements ServiceInterface {
+ private final Ensure m_ensure;
+ public ServiceProvider(Ensure e) {
+ m_ensure = e;
+ }
+ public void invoke(Runnable run) {
+ run.run();
+ }
+ }
+
+ static class ServiceAspect implements ServiceInterface {
+ private final Ensure m_ensure;
+ private volatile ServiceInterface m_parentService;
+ private final int m_step;
+
+ public ServiceAspect(Ensure e, int step) {
+ m_ensure = e;
+ m_step = step;
+ }
+ public void start() {
+ }
+
+ public void invoke(Runnable run) {
+ m_ensure.step(m_step);
+ m_parentService.invoke(run);
+ }
+
+ public void stop() {
+ }
+ }
+
+ static class ServiceConsumer implements Runnable {
+ private volatile ServiceInterface m_service;
+ private final Ensure m_ensure;
+
+ public ServiceConsumer(Ensure e) {
+ m_ensure = e;
+ }
+
+ public void init() {
+ Thread t = new Thread(this);
+ t.start();
+ }
+
+ public void run() {
+ m_ensure.waitForStep(1, 2000);
+ m_service.invoke(Ensure.createRunnableStep(m_ensure, 5));
+ }
+ }
+}
Propchange: felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectChainTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectDynamicsTest.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectDynamicsTest.java?rev=1595756&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectDynamicsTest.java (added)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectDynamicsTest.java Mon May 19 06:47:07 2014
@@ -0,0 +1,145 @@
+package dm.it;
+import dm.Component;
+import dm.DependencyManager;
+
+public class AspectDynamicsTest extends TestBase {
+
+ public void testDynamicallyAddAndRemoveAspect() {
+ DependencyManager m = new DependencyManager(context);
+ // helper class that ensures certain steps get executed in sequence
+ Ensure e = new Ensure();
+ // create a service provider and consumer
+ Component provider = m.createComponent().setImplementation(new ServiceProvider(e)).setInterface(ServiceInterface.class.getName(), null);
+ Component provider2 = m.createComponent().setImplementation(new ServiceProvider2(e)).setInterface(ServiceInterface2.class.getName(), null);
+ Component consumer = m.createComponent().setImplementation(new ServiceConsumer(e)).add(m.createServiceDependency().setService(ServiceInterface.class).setRequired(true));
+ Component aspect = m.createAspectService(ServiceInterface.class, null, 1, null).setImplementation(new ServiceAspect(e));
+
+ m.add(consumer);
+ m.add(provider);
+ // the consumer should invoke the provider here, and when done, arrive at step 3
+ // finally wait for step 6 before continuing
+ e.waitForStep(3, 15000);
+
+ m.add(aspect);
+ // after adding the aspect, we wait for its init to be invoked, arriving at
+ // step 4 after an instance bound dependency was added (on a service provided by
+ // provider 2)
+ e.waitForStep(4, 15000);
+
+ m.add(provider2);
+
+ // after adding provider 2, we should now see the aspect being started, so
+ // we wait for step 5 to happen
+ e.waitForStep(5, 15000);
+
+ // now we continue with step 6, which will trigger the next part of the consumer's
+ // run method to be executed
+ e.step(6);
+
+ // invoking step 7, 8 and 9 when invoking the aspect which in turn invokes the
+ // dependency and the original service, so we wait for that to finish here, which
+ // is after step 10 has been reached (the client will now wait for step 12)
+ e.waitForStep(10, 15000);
+
+ m.remove(aspect);
+ // removing the aspect should trigger step 11 (in the stop method of the aspect)
+ e.waitForStep(11, 15000);
+
+ // step 12 triggers the client to continue
+ e.step(12);
+
+ // wait for step 13, the final invocation of the provided service (without aspect)
+ e.waitForStep(13, 15000);
+
+ // clean up
+ m.remove(provider2);
+ m.remove(provider);
+ m.remove(consumer);
+ }
+
+ static interface ServiceInterface {
+ public void invoke(Runnable run);
+ }
+
+ static interface ServiceInterface2 {
+ public void invoke();
+ }
+
+ static class ServiceProvider2 implements ServiceInterface2 {
+ private final Ensure m_ensure;
+
+ public ServiceProvider2(Ensure ensure) {
+ m_ensure = ensure;
+ }
+
+ public void invoke() {
+ m_ensure.step(9);
+ }
+ }
+
+ static class ServiceProvider implements ServiceInterface {
+ private final Ensure m_ensure;
+ public ServiceProvider(Ensure e) {
+ m_ensure = e;
+ }
+ public void invoke(Runnable run) {
+ run.run();
+ }
+ }
+
+ static class ServiceAspect implements ServiceInterface {
+ private final Ensure m_ensure;
+ private volatile ServiceInterface m_originalService;
+ private volatile ServiceInterface2 m_injectedService;
+ private volatile Component m_service;
+ private volatile DependencyManager m_manager;
+
+ public ServiceAspect(Ensure e) {
+ m_ensure = e;
+ }
+ public void init() {
+ m_service.add(m_manager.createServiceDependency()
+ .setService(ServiceInterface2.class)
+ .setRequired(true)
+ );
+ m_ensure.step(4);
+ }
+ public void start() {
+ m_ensure.step(5);
+ }
+ public void invoke(Runnable run) {
+ m_ensure.step(7);
+ m_originalService.invoke(run);
+ m_injectedService.invoke();
+ }
+
+ public void stop() {
+ m_ensure.step(11);
+ }
+ }
+
+ static class ServiceConsumer implements Runnable {
+ private volatile ServiceInterface m_service;
+ private final Ensure m_ensure;
+
+ public ServiceConsumer(Ensure e) {
+ m_ensure = e;
+ }
+
+ public void init() {
+ Thread t = new Thread(this);
+ t.start();
+ }
+
+ public void run() {
+ m_ensure.step(1);
+ m_service.invoke(Ensure.createRunnableStep(m_ensure, 2));
+ m_ensure.step(3);
+ m_ensure.waitForStep(6, 15000);
+ m_service.invoke(Ensure.createRunnableStep(m_ensure, 8));
+ m_ensure.step(10);
+ m_ensure.waitForStep(12, 15000);
+ m_service.invoke(Ensure.createRunnableStep(m_ensure, 13));
+ }
+ }
+}
Propchange: felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectDynamicsTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectRaceTest.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectRaceTest.java?rev=1595756&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectRaceTest.java (added)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectRaceTest.java Mon May 19 06:47:07 2014
@@ -0,0 +1,343 @@
+package dm.it;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import junit.framework.Assert;
+
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+
+import dm.Component;
+import dm.DependencyManager;
+import dm.ServiceDependency;
+
+public class AspectRaceTest extends TestBase {
+ volatile ExecutorService m_serviceExec;
+ volatile ExecutorService m_aspectExec;
+ volatile DependencyManager m_dm;
+ final static int SERVICES = 1; // 3;
+ final static int ASPECTS_PER_SERVICE = 2;
+ final static int ITERATIONS = 3000; // 3000;
+
+ public void testConcurrentAspects() {
+ try {
+ warn("starting aspect race test");
+ int cores = Math.max(4, Runtime.getRuntime().availableProcessors());
+ // Used to inject S services
+ m_serviceExec = Executors.newFixedThreadPool(cores);
+ // Used to inject S Aspects
+ m_aspectExec = Executors.newFixedThreadPool(cores);
+
+ // Setup test components using dependency manager.
+ // We create a Controller which is injected with some S services,
+ // and each S services has some aspects (SAspect).
+
+ m_dm = new DependencyManager(context);
+ Controller controller = new Controller();
+ ServiceDependency dependency = m_dm.createServiceDependency().setService(S.class)
+ .setCallbacks("bind", null, "unbind", "swap")
+ .setRequired(true);
+// dependency.setDebug("controller");
+ Component c = m_dm
+ .createComponent()
+ .setImplementation(controller)
+ .setInterface(Controller.class.getName(), null)
+ .setComposition("getComposition")
+ .add(dependency);
+
+ m_dm.add(c);
+
+ for (int loop = 1; loop <= ITERATIONS; loop++) {
+ System.out.println("\niteration: " + loop);
+ // Perform concurrent injections of "S" service and S aspects
+ // into the Controller component;
+ debug("Iteration: " + loop);
+ Factory f = new Factory();
+ f.register();
+
+// System.out.println("Checking...");
+
+ controller.check();
+
+// System.out.println("Done checking...");
+
+ // unregister all services and aspects concurrently
+ f.unregister();
+
+ if ((loop) % 100 == 0) {
+ warn("Performed " + loop + " tests.");
+ }
+
+ if (super.errorsLogged()) {
+ throw new IllegalStateException("Race test interrupted (some error occured, see previous logs)");
+ }
+ }
+ }
+
+ catch (Throwable t) {
+ error("Test failed", t);
+ Assert.fail("Test failed: " + t.getMessage());
+ } finally {
+ shutdown(m_serviceExec);
+ shutdown(m_aspectExec);
+ m_dm.clear();
+ }
+ }
+
+ void shutdown(ExecutorService exec) {
+ exec.shutdown();
+ try {
+ exec.awaitTermination(5, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ }
+ }
+
+ public interface S {
+ void invoke(Ensure e);
+ }
+
+ public static class SImpl implements S {
+ final int m_step;
+
+ SImpl(int step) {
+ m_step = step;
+ }
+
+ public void invoke(Ensure e) {
+ e.step(m_step);
+ }
+
+ public String toString() {
+ return "SImpl[" + m_step + "]";
+ }
+ }
+
+ public static class SAspect implements S {
+ volatile S m_next;
+ final int m_rank;
+ final int m_step;
+ final int m_id;
+ volatile Component m_component;
+
+ SAspect(int id, int rank) {
+ m_rank = rank;
+ m_id = id;
+ m_step = ASPECTS_PER_SERVICE - rank + 1;
+ }
+
+ public synchronized void added(S s) {
+ System.out.println(Thread.currentThread().getId() + " ARTA aspect added " + m_rank + ": " + s );
+ if (m_next != null) {
+ fail("Adding while expected swap... " + m_rank);
+ }
+ m_next = s;
+ }
+
+ public synchronized void swap(S oldS, S newS) {
+ System.out.println(Thread.currentThread().getId() + " ARTA aspect swap " + m_rank + ": " + oldS + " with " + newS);
+ m_next = newS;
+ }
+
+ public synchronized void removed(S s) {
+ System.out.println(Thread.currentThread().getId() + " ARTA aspect removed " + m_rank + ": " + s );
+ m_next = null;
+ }
+
+ public synchronized void invoke(Ensure e) {
+// System.out.println("config " + m_rank + ": " + toString() + " " + m_component.getExecutor() + " " + m_component);
+ e.step(m_step);
+ m_next.invoke(e);
+ }
+
+ public String toString() {
+ return "SAspect[" + m_id + ", " + m_rank + ", " + m_step + "], " + m_next.toString();
+ }
+ }
+
+ class Factory {
+ final ConcurrentLinkedQueue<Component> m_services = new ConcurrentLinkedQueue<Component>();
+ final ConcurrentLinkedQueue<Component> m_aspects = new ConcurrentLinkedQueue<Component>();
+
+ public void register() throws InterruptedException {
+ final CountDownLatch latch = new CountDownLatch(SERVICES
+ + (ASPECTS_PER_SERVICE * SERVICES));
+
+ for (int i = 1; i <= SERVICES; i++) {
+ final int serviceId = i;
+ m_serviceExec.execute(new Runnable() {
+ public void run() {
+ try {
+ Component c = m_dm.createComponent();
+ Hashtable<String, String> props = new Hashtable<String, String>();
+ props.put("id", String.valueOf(serviceId));
+ c.setInterface(S.class.getName(), props)
+ .setImplementation(
+ new SImpl(ASPECTS_PER_SERVICE + 1));
+ m_services.add(c);
+ m_dm.add(c);
+ latch.countDown();
+ } catch (Throwable e) {
+ error(e);
+ }
+ }
+ });
+
+ for (int j = 1; j <= ASPECTS_PER_SERVICE; j++) {
+ final int rank = j;
+ m_aspectExec.execute(new Runnable() {
+ public void run() {
+ try {
+ SAspect sa = new SAspect(serviceId, rank);
+ Component aspect = m_dm.createAspectService(
+ S.class, "(id=" + serviceId + ")",
+ rank, "added", "removed", null, "swap")
+ .setImplementation(sa);
+ m_aspects.add(aspect);
+ m_dm.add(aspect);
+ latch.countDown();
+ } catch (Throwable e) {
+ error(e);
+ }
+ }
+ });
+ }
+ }
+
+ if (!latch.await(5000, TimeUnit.MILLISECONDS)) {
+ throw new IllegalStateException(
+ "could not register services and aspects timely");
+ }
+
+ debug("all registered: aspects=" + m_aspects);
+// System.out.println("all registered: aspects=" + m_aspects);
+ // Thread.sleep(5000);
+ }
+
+ public void unregister() throws InterruptedException,
+ InvalidSyntaxException {
+ final CountDownLatch latch = new CountDownLatch(SERVICES
+ + (ASPECTS_PER_SERVICE * SERVICES));
+
+ unregisterAspects(latch);
+ unregisterServices(latch);
+
+ if (!latch.await(5000, TimeUnit.MILLISECONDS)) {
+ throw new IllegalStateException(
+ "could not unregister services and aspects timely");
+ }
+
+ if (context.getServiceReference(S.class.getName()) != null) {
+ error("could not unregister some services or aspects !");
+ }
+ debug("unregistered all aspects and services concurrently");
+ }
+
+ public void unregisterAspects(final CountDownLatch latch)
+ throws InterruptedException, InvalidSyntaxException {
+ Component c;
+ debug("unregister: aspects=" + m_aspects);
+
+ while ((c = m_aspects.poll()) != null) {
+ final Component c$ = c;
+ m_serviceExec.execute(new Runnable() {
+ public void run() {
+ try {
+ debug("removing service " + c$);
+ m_dm.remove(c$);
+ latch.countDown();
+ } catch (Throwable e) {
+ error(e);
+ }
+ }
+ });
+ }
+ }
+
+ public void unregisterServices(final CountDownLatch latch)
+ throws InterruptedException {
+ Component c;
+ debug("unregister: services=" + m_services);
+
+ while ((c = m_services.poll()) != null) {
+ final Component c$ = c;
+ m_serviceExec.execute(new Runnable() {
+ public void run() {
+ try {
+ debug("removing service " + c$);
+ m_dm.remove(c$);
+ latch.countDown();
+ } catch (Throwable e) {
+ error(e);
+ }
+ }
+ });
+ }
+
+ debug("unregistered all services");
+ }
+ }
+
+ public class Controller {
+ final Composition m_compo = new Composition();
+ final HashSet<S> m_services = new HashSet<S>();
+
+ Object[] getComposition() {
+ return new Object[] { this, m_compo };
+ }
+
+ void bind(ServiceReference sr, Object service) {
+// System.out.println("ARTC bind... " + service);
+ S s = (S) sr.getBundle().getBundleContext().getService(sr);
+ if (s == null) {
+ throw new IllegalStateException(
+ "bindA: bundleContext.getService returned null");
+ }
+ debug("bind " + s);
+ synchronized (this) {
+ m_services.add(s);
+// System.out.println("service count after bind: " + m_services.size());
+ }
+ }
+
+ void swap(S previous, S current) {
+// System.out.println("swap...");
+// System.out.println("ARTC swap: " + previous + " with " + current);
+ synchronized (this) {
+ if (!m_services.remove(previous)) {
+ System.out.println("swap: unknow previous service: " + previous);
+ }
+ m_services.add(current);
+// System.out.println("service count after swap: " + m_services.size());
+ }
+ }
+
+ void unbind(S a) {
+// System.out.println("ARTC unbind...");
+ debug("unbind " + a);
+ synchronized (this) {
+ m_services.remove(a);
+// System.out.println("service count after unbind: " + m_services.size());
+ }
+ }
+
+ void check() {
+ synchronized (this) {
+// System.out.println("service count: " + m_services.size());
+ for (S s : m_services) {
+// System.out.println("checking service: " + s);
+ debug("checking service: " + s + " ...");
+ Ensure ensure = new Ensure(false);
+ s.invoke(ensure);
+ }
+ }
+ }
+ }
+
+ public static class Composition {
+ }
+}
\ No newline at end of file
Propchange: felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectRaceTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectServiceDependencyTest.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectServiceDependencyTest.java?rev=1595756&r1=1595755&r2=1595756&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectServiceDependencyTest.java (original)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectServiceDependencyTest.java Mon May 19 06:47:07 2014
@@ -29,20 +29,25 @@ public class AspectServiceDependencyTest
Ensure e = new Ensure();
// create a service provider and consumer
Component sp = m.createComponent().setImplementation(new ServiceProvider(e)).setInterface(ServiceInterface.class.getName(), null);
- Component sc = m.createComponent().setImplementation(new ServiceConsumer(e)).add(m.createServiceDependency().setService(ServiceInterface.class).setRequired(true));
+ Component sc = m.createComponent().setImplementation(new ServiceConsumer(e)).add(m.createServiceDependency()
+ .setService(ServiceInterface.class)
+ .setCallbacks("add", "remove")
+ .setRequired(true));
+ Component asp = m.createAspectService(ServiceInterface.class, null, 100)
+ .setImplementation(ServiceProviderAspect.class);
m.add(sp);
m.add(sc);
+ m.add(asp);
+ m.remove(asp);
m.remove(sc);
m.remove(sp);
- // TODO: Further implementation when aspect services have been implemented.
-
// ensure we executed all steps inside the component instance
- e.step(4);
+ e.step(8);
}
static interface ServiceInterface {
- public void invoke();
+ public void invoke(String caller);
}
static class ServiceProvider implements ServiceInterface {
@@ -50,41 +55,63 @@ public class AspectServiceDependencyTest
public ServiceProvider(Ensure e) {
m_ensure = e;
}
- public void invoke() {
- m_ensure.step(2);
+ public void invoke(String caller) {
+ if (caller.equals("consumer.init")) {
+ m_ensure.step(3);
+ } else if (caller.equals("aspect.consumer.add")) {
+ m_ensure.step(5);
+ }
}
}
+
+ static class ServiceProviderAspect implements ServiceInterface {
+ private volatile ServiceInterface m_service;
+
+ public ServiceProviderAspect() {
+ }
+
+ @Override
+ public void invoke(String caller) {
+ m_service.invoke("aspect." + caller);
+ }
+ }
static class ServiceConsumer {
private volatile ServiceInterface m_service;
private final Ensure m_ensure;
+ private int addCount = 0;
public ServiceConsumer(Ensure e) {
m_ensure = e;
}
public void init() {
- m_ensure.step(1);
- m_service.invoke();
+ m_ensure.step(2);
+ m_service.invoke("consumer.init");
}
public void destroy() {
- m_ensure.step(3);
- }
- }
-
- static class ServiceConsumerCallbacks {
- private final Ensure m_ensure;
-
- public ServiceConsumerCallbacks(Ensure e) {
- m_ensure = e;
+ m_ensure.step(7);
}
public void add(ServiceInterface service) {
- m_ensure.step(4);
+ m_service = service;
+ switch (addCount) {
+ case 0: m_ensure.step(1);
+ break;
+ case 1: m_ensure.step(4);
+ // aspect had been added
+ m_service.invoke("consumer.add");
+ break;
+ case 2: m_ensure.step(6);
+ break;
+ default:
+ }
+ addCount ++;
}
public void remove(ServiceInterface service) {
- m_ensure.step(5);
- }
+ m_service = null;
+ }
}
+
}
Added: felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectServiceDependencyWithSwapCallbackTest.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectServiceDependencyWithSwapCallbackTest.java?rev=1595756&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectServiceDependencyWithSwapCallbackTest.java (added)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectServiceDependencyWithSwapCallbackTest.java Mon May 19 06:47:07 2014
@@ -0,0 +1,119 @@
+/*
+ * 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 dm.it;
+
+import dm.Component;
+import dm.DependencyManager;
+
+
+public class AspectServiceDependencyWithSwapCallbackTest extends TestBase {
+ public void testServiceRegistrationAndConsumption() {
+ DependencyManager m = new DependencyManager(context);
+ // helper class that ensures certain steps get executed in sequence
+ Ensure e = new Ensure();
+ // create a service provider and consumer
+ Component sp = m.createComponent().setImplementation(new ServiceProvider(e)).setInterface(ServiceInterface.class.getName(), null);
+ Component sc = m.createComponent().setImplementation(new ServiceConsumer(e)).add(m.createServiceDependency()
+ .setService(ServiceInterface.class)
+ .setCallbacks("add", null, "remove", "swap")
+ .setRequired(true));
+ Component asp = m.createAspectService(ServiceInterface.class, null, 100)
+ .setImplementation(ServiceProviderAspect.class);
+ m.add(sp);
+ m.add(sc);
+ m.add(asp);
+ m.remove(asp);
+ m.remove(sc);
+ m.remove(sp);
+
+ // ensure we executed all steps inside the component instance
+ e.step(7);
+ }
+
+ static interface ServiceInterface {
+ public void invoke(String caller);
+ }
+
+ static class ServiceProvider implements ServiceInterface {
+ private final Ensure m_ensure;
+ public ServiceProvider(Ensure e) {
+ m_ensure = e;
+ }
+ public void invoke(String caller) {
+ if (caller.equals("consumer.init")) {
+ m_ensure.step(3);
+ } else if (caller.equals("aspect.consumer.add")) {
+ m_ensure.step(5);
+ }
+ }
+ }
+
+ static class ServiceProviderAspect implements ServiceInterface {
+ private volatile ServiceInterface m_service;
+
+ public ServiceProviderAspect() {
+ }
+
+ @Override
+ public void invoke(String caller) {
+ m_service.invoke("aspect." + caller);
+ }
+ }
+
+ static class ServiceConsumer {
+ private volatile ServiceInterface m_service;
+ private final Ensure m_ensure;
+ private int swapCount = 0;
+
+ public ServiceConsumer(Ensure e) {
+ m_ensure = e;
+ }
+
+ public void init() {
+ m_ensure.step(2);
+ m_service.invoke("consumer.init");
+ }
+
+ public void destroy() {
+ m_ensure.step(6);
+ }
+
+ public void add(ServiceInterface service) {
+ m_service = service;
+ m_ensure.step(1);
+ }
+
+ public void remove(ServiceInterface service) {
+ m_service = null;
+ }
+
+ public void swap(ServiceInterface previous, ServiceInterface current) {
+ switch (swapCount) {
+ case 0: m_ensure.step(4);
+ break;
+ case 1: m_ensure.step(5);
+ break;
+ default:
+ }
+ m_service = current;
+ swapCount ++;
+ }
+ }
+
+}
Propchange: felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectServiceDependencyWithSwapCallbackTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectWhiteboardTest.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectWhiteboardTest.java?rev=1595756&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectWhiteboardTest.java (added)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectWhiteboardTest.java Mon May 19 06:47:07 2014
@@ -0,0 +1,177 @@
+package dm.it;
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.Assert;
+
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+import dm.Component;
+import dm.DependencyManager;
+
+public class AspectWhiteboardTest extends TestBase {
+
+ public void testWhiteboardConsumer() {
+ DependencyManager m = new DependencyManager(context);
+ // helper class that ensures certain steps get executed in sequence
+ Ensure e = new Ensure();
+ // create service providers and consumer
+ Component sp1 = m.createComponent().setImplementation(new ServiceProvider(e)).setInterface(ServiceInterface.class.getName(), null);
+ Component sp2 = m.createComponent().setImplementation(new ServiceProvider(e)).setInterface(ServiceInterface.class.getName(), null);
+ ServiceConsumer sci = new ServiceConsumer(e);
+ Component sc = m.createComponent().setImplementation(sci).add(m.createServiceDependency().setService(ServiceInterface.class).setRequired(false).setCallbacks("add", "remove"));
+ Component sa2 = m.createAspectService(ServiceInterface.class, null, 20, null).setImplementation(new ServiceAspect(e, 3));
+ Component sa1 = m.createAspectService(ServiceInterface.class, null, 10, null).setImplementation(new ServiceAspect(e, 4));
+
+ // start with a service consumer
+ System.out.println("Adding consumer");
+ m.add(sc);
+
+ // then add two providers, so the consumer will see two services
+ System.out.println("Adding 2 providers");
+ m.add(sp1);
+ m.add(sp2);
+
+ // make sure consumer sees both services
+ Assert.assertEquals(2, sci.services());
+
+ // add an aspect with ranking 20
+ System.out.println("Adding aspect with rank 20");
+ m.add(sa2);
+
+ // make sure the consumer sees the two new aspects and no longer sees the two original services
+ Assert.assertEquals(2, sci.services());
+ Assert.assertEquals(20, sci.highestRanking());
+ Assert.assertEquals(20, sci.lowestRanking());
+
+ // add an aspect with ranking 10
+ System.out.println("Adding aspect with rank 10");
+ m.add(sa1);
+
+ // make sure the consumer still sees the two aspects with ranking 20
+ Assert.assertEquals(2, sci.services());
+ Assert.assertEquals(20, sci.highestRanking());
+ Assert.assertEquals(20, sci.lowestRanking());
+
+ // remove the aspect with ranking 20
+ System.out.println("Removing aspect with rank 20");
+ m.remove(sa2);
+
+ // make sure the consumer now sees the aspects with ranking 10
+ Assert.assertEquals(2, sci.services());
+ Assert.assertEquals(10, sci.highestRanking());
+ Assert.assertEquals(10, sci.lowestRanking());
+
+ // remove one of the original services
+ System.out.println("Removing 1 service");
+ m.remove(sp1);
+
+ // make sure the aspect of that service goes away
+ Assert.assertEquals(1, sci.services());
+ Assert.assertEquals(10, sci.highestRanking());
+ Assert.assertEquals(10, sci.lowestRanking());
+
+ // remove the aspect with ranking 10
+ System.out.println("Removing aspect with rank 10");
+ m.remove(sa1);
+
+ // make sure only the original service remains
+ Assert.assertEquals(1, sci.services());
+ Assert.assertEquals(0, sci.highestRanking());
+ Assert.assertEquals(0, sci.lowestRanking());
+
+ System.out.println("Done with test");
+
+ // end of test
+ m.remove(sa2);
+ m.remove(sp2);
+ m.remove(sc);
+ }
+
+ static interface ServiceInterface {
+ public void invoke(Runnable run);
+ }
+
+ static class ServiceProvider implements ServiceInterface {
+ private final Ensure m_ensure;
+ public ServiceProvider(Ensure e) {
+ m_ensure = e;
+ }
+ public void invoke(Runnable run) {
+ run.run();
+ }
+ }
+
+ static class ServiceAspect implements ServiceInterface {
+ private final Ensure m_ensure;
+ private volatile ServiceInterface m_parentService;
+ private final int m_step;
+
+ public ServiceAspect(Ensure e, int step) {
+ m_ensure = e;
+ m_step = step;
+ }
+ public void start() {
+ }
+
+ public void invoke(Runnable run) {
+ m_ensure.step(m_step);
+ m_parentService.invoke(run);
+ }
+
+ public void stop() {
+ }
+ }
+
+ static class ServiceConsumer implements Runnable {
+ private List m_services = new ArrayList();
+ private final Ensure m_ensure;
+
+ public ServiceConsumer(Ensure e) {
+ m_ensure = e;
+ }
+
+ public void init() {
+ Thread t = new Thread(this);
+ t.start();
+ }
+
+ public void run() {
+ }
+
+ public int services() {
+ return m_services.size();
+ }
+
+ public int highestRanking() {
+ int ranking = Integer.MIN_VALUE;
+ for (int i = 0; i < m_services.size(); i++) {
+ ServiceReference ref = (ServiceReference) m_services.get(i);
+ Integer r = (Integer) ref.getProperty(Constants.SERVICE_RANKING);
+ int rank = r == null ? 0 : r.intValue();
+ ranking = Math.max(ranking, rank);
+ }
+ return ranking;
+ }
+ public int lowestRanking() {
+ int ranking = Integer.MAX_VALUE;
+ for (int i = 0; i < m_services.size(); i++) {
+ ServiceReference ref = (ServiceReference) m_services.get(i);
+ Integer r = (Integer) ref.getProperty(Constants.SERVICE_RANKING);
+ int rank = r == null ? 0 : r.intValue();
+ ranking = Math.min(ranking, rank);
+ }
+ return ranking;
+ }
+
+ public void add(ServiceReference ref, ServiceInterface svc) {
+ System.out.println("Added: " + ServiceUtil.toString(ref));
+ m_services.add(ref);
+ }
+ public void remove(ServiceReference ref, ServiceInterface svc) {
+ System.out.println("Removed: " + ServiceUtil.toString(ref));
+ m_services.remove(ref);
+ }
+ }
+}
Propchange: felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectWhiteboardTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectWithCallbacksServiceDependencyTest.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectWithCallbacksServiceDependencyTest.java?rev=1595756&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectWithCallbacksServiceDependencyTest.java (added)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectWithCallbacksServiceDependencyTest.java Mon May 19 06:47:07 2014
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package dm.it;
+
+import dm.Component;
+import dm.DependencyManager;
+
+
+public class AspectWithCallbacksServiceDependencyTest extends TestBase {
+ public void testServiceRegistrationAndConsumption() {
+ DependencyManager m = new DependencyManager(context);
+ // helper class that ensures certain steps get executed in sequence
+ Ensure e = new Ensure();
+ // create a service provider and consumer
+ Component sp = m.createComponent().setImplementation(new ServiceProvider(e)).setInterface(ServiceInterface.class.getName(), null);
+ Component sc = m.createComponent().setImplementation(new ServiceConsumer(e)).add(m.createServiceDependency()
+ .setService(ServiceInterface.class)
+ .setCallbacks("add", "remove")
+ .setRequired(true));
+ Component asp = m.createAspectService(ServiceInterface.class, null, 100, "add", null, "remove", "swap")
+ .setImplementation(ServiceProviderAspect.class);
+ m.add(sp);
+ m.add(sc);
+ m.add(asp);
+ m.remove(asp);
+ m.remove(sc);
+ m.remove(sp);
+
+ // ensure we executed all steps inside the component instance
+ e.step(8);
+ }
+
+ static interface ServiceInterface {
+ public void invoke(String caller);
+ }
+
+ static class ServiceProvider implements ServiceInterface {
+ private final Ensure m_ensure;
+ public ServiceProvider(Ensure e) {
+ m_ensure = e;
+ }
+ public void invoke(String caller) {
+ if (caller.equals("consumer.init")) {
+ m_ensure.step(3);
+ } else if (caller.equals("aspect.consumer.add")) {
+ m_ensure.step(5);
+ }
+ }
+ }
+
+ static class ServiceProviderAspect implements ServiceInterface {
+ private volatile ServiceInterface m_service;
+
+ public ServiceProviderAspect() {
+ }
+
+ @Override
+ public void invoke(String caller) {
+ m_service.invoke("aspect." + caller);
+ }
+
+ public void add(ServiceInterface service) {
+ m_service = service;
+ }
+
+ public void remove(ServiceInterface service) {
+ m_service = null;
+ }
+
+ public void swap(ServiceInterface previous, ServiceInterface current) {
+ m_service = current;
+ }
+ }
+
+ static class ServiceConsumer {
+ private volatile ServiceInterface m_service;
+ private final Ensure m_ensure;
+ private int addCount = 0;
+
+ public ServiceConsumer(Ensure e) {
+ m_ensure = e;
+ }
+
+ public void init() {
+ m_ensure.step(2);
+ m_service.invoke("consumer.init");
+ }
+
+ public void destroy() {
+ m_ensure.step(7);
+ }
+
+ public void add(ServiceInterface service) {
+ m_service = service;
+ switch (addCount) {
+ case 0: m_ensure.step(1);
+ break;
+ case 1: m_ensure.step(4);
+ // aspect had been added
+ m_service.invoke("consumer.add");
+ break;
+ case 2: m_ensure.step(6);
+ break;
+ default:
+ }
+ addCount ++;
+ }
+ public void remove(ServiceInterface service) {
+ m_service = null;
+ }
+ }
+
+}
Propchange: felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectWithCallbacksServiceDependencyTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectWithPropagationTest.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectWithPropagationTest.java?rev=1595756&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectWithPropagationTest.java (added)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectWithPropagationTest.java Mon May 19 06:47:07 2014
@@ -0,0 +1,652 @@
+package dm.it;
+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 junit.framework.Assert;
+
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+import dm.Component;
+import dm.DependencyManager;
+
+/**
+ * Test for aspects with service properties propagations.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+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
+ * - Create some S Aspects
+ * - 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 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 = new DependencyManager(context);
+ // 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 (_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 = new DependencyManager(context);
+ // 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 (_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 = new DependencyManager(context);
+ 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 (_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 = new DependencyManager(context);
+ 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", "remove"));
+
+ // 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 (_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.
+ }
+ }
+ }
+}
Propchange: felix/sandbox/pderop/dependencymanager-prototype/dm.it/src/dm/it/AspectWithPropagationTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/Component.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/Component.java?rev=1595756&r1=1595755&r2=1595756&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/Component.java (original)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/Component.java Mon May 19 06:47:07 2014
@@ -33,4 +33,8 @@ public interface Component {
public DependencyManager getDependencyManager();
public ComponentDeclaration getComponentDeclaration();
public Component setExecutor(Executor executor);
+
+ // TODO ASPECTS: Methods added for debugging AspectRaceTest, but we might just leave the 'debug' features in there.
+ public Executor getExecutor();
+ public void setDebug(String string);
}
Modified: felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/DependencyActivatorBase.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/DependencyActivatorBase.java?rev=1595756&r1=1595755&r2=1595756&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/DependencyActivatorBase.java (original)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/DependencyActivatorBase.java Mon May 19 06:47:07 2014
@@ -18,10 +18,11 @@
*/
package dm;
-import dm.impl.Logger;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
+import dm.impl.Logger;
+
/**
* Base bundle activator class. Subclass this activator if you want to use dependency
* management in your bundle. There are two methods you should implement:
Modified: felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/DependencyManager.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/DependencyManager.java?rev=1595756&r1=1595755&r2=1595756&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/DependencyManager.java (original)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/DependencyManager.java Mon May 19 06:47:07 2014
@@ -32,12 +32,13 @@ import org.osgi.framework.BundleExceptio
import org.osgi.framework.FrameworkUtil;
import dm.context.ComponentContext;
-import dm.impl.FactoryConfigurationAdapterImpl;
import dm.impl.AdapterServiceImpl;
+import dm.impl.AspectServiceImpl;
import dm.impl.BundleAdapterImpl;
import dm.impl.BundleDependencyImpl;
import dm.impl.ComponentImpl;
import dm.impl.ConfigurationDependencyImpl;
+import dm.impl.FactoryConfigurationAdapterImpl;
import dm.impl.Logger;
import dm.impl.ResourceAdapterImpl;
import dm.impl.ResourceDependencyImpl;
@@ -222,24 +223,20 @@ public class DependencyManager {
return m_components;
}
- public Component createAspectService(Class serviceInterface, String serviceFilter, int ranking, String attributeName) {
- // TODO
- return null;
+ public Component createAspectService(Class serviceInterface, String serviceFilter, int ranking, String autoConfig) {
+ return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, autoConfig, null, null, null, null);
}
public Component createAspectService(Class serviceInterface, String serviceFilter, int ranking) {
- // TODO
- return null;
+ return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, null, null, null, null, null);
}
public Component createAspectService(Class serviceInterface, String serviceFilter, int ranking, String add, String change, String remove) {
- // TODO
- return null;
+ return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, null, add, change, remove, null);
}
public Component createAspectService(Class serviceInterface, String serviceFilter, int ranking, String add, String change, String remove, String swap) {
- // TODO
- return null;
+ return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, null, add, change, remove, swap);
}
public void clear() {
Modified: felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/ServiceDependency.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/ServiceDependency.java?rev=1595756&r1=1595755&r2=1595756&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/ServiceDependency.java (original)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/ServiceDependency.java Mon May 19 06:47:07 2014
@@ -20,4 +20,7 @@ public interface ServiceDependency exten
public ServiceDependency setDefaultImplementation(Object implementation);
public ServiceDependency setPropagate(boolean propagate);
public ServiceDependency setPropagate(Object instance, String method);
+
+ // TODO ASPECTS: Added debug option. Decide whether we might just leave it in.
+ public void setDebug(String debugKey);
}
Modified: felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/AbstractDecorator.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/AbstractDecorator.java?rev=1595756&r1=1595755&r2=1595756&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/AbstractDecorator.java (original)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/AbstractDecorator.java Mon May 19 06:47:07 2014
@@ -20,7 +20,6 @@ package dm.impl;
import java.net.URL;
import java.util.Dictionary;
-import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;