Search in sources :

Example 1 with ComponentStateListener

use of org.apache.felix.dm.ComponentStateListener in project felix by apache.

the class ConcurrencyTest method createComponentAddDependencyAndListenerAndAddAnotherDependencyInAParallelThread.

/**
 * Ensure actions from another thread than the current thread executing in the SerialExecutor are being
 * scheduled (added to the queue) rather than being executed immediately.
 */
@Test
public void createComponentAddDependencyAndListenerAndAddAnotherDependencyInAParallelThread() {
    final Semaphore s = new Semaphore(0);
    final ComponentImpl c = new ComponentImpl();
    final SimpleServiceDependency d = new SimpleServiceDependency();
    d.setRequired(true);
    final SimpleServiceDependency d2 = new SimpleServiceDependency();
    d2.setRequired(true);
    final Thread t = new Thread() {

        public void run() {
            c.add(d2);
            s.release();
        }
    };
    ComponentStateListener l = new ComponentStateListener() {

        @Override
        public void changed(Component component, ComponentState state) {
            try {
                c.remove(this);
                // launch a second thread interacting with our ComponentImpl and block this thread until the
                // second thread finished its interaction with our component. We want to ensure the work of
                // the second thread is scheduled after our current job in the serial executor and does not
                // get executed immediately.
                t.start();
                s.acquire();
                Assert.assertEquals("dependency count should be 1", 1, c.getDependencies().size());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };
    // If not, we may see NullPointers when invoking lifecycle callbacks
    c.setImplementation(new Object());
    c.start();
    c.add(d);
    c.add(l);
    Assert.assertEquals("component should not be available", false, c.isAvailable());
    // sets dependency d to available and triggers our ComponentStateListener
    d.add(new EventImpl());
    // due to the dependency added by the second thread in the serial executor we still expect our component
    // to be unavailable. This work was scheduled in the serial executor and will be executed by the current
    // thread after it finished handling the job for handling the changed() method.
    Assert.assertEquals("component should not be available", false, c.isAvailable());
    c.remove(l);
    Assert.assertEquals("component should not be available", false, c.isAvailable());
    c.remove(d);
    Assert.assertEquals("component should not be available", false, c.isAvailable());
    c.remove(d2);
    Assert.assertEquals("component should be available", true, c.isAvailable());
    c.stop();
    Assert.assertEquals("component should not be available", false, c.isAvailable());
}
Also used : Semaphore(java.util.concurrent.Semaphore) Component(org.apache.felix.dm.Component) ComponentImpl(org.apache.felix.dm.impl.ComponentImpl) ComponentStateListener(org.apache.felix.dm.ComponentStateListener) ComponentState(org.apache.felix.dm.ComponentState) Test(org.junit.Test)

Example 2 with ComponentStateListener

use of org.apache.felix.dm.ComponentStateListener in project felix by apache.

the class ServiceRaceTest method doTest.

void doTest(int loop) throws Throwable {
    debug("loop#%d -------------------------", loop);
    final Ensure step = new Ensure(false);
    // Create one client component, which depends on many service dependencies
    final ComponentImpl client = new ComponentImpl();
    final Client theClient = new Client(step);
    client.setImplementation(theClient);
    // Create client service dependencies
    final SimpleServiceDependency[] dependencies = new SimpleServiceDependency[DEPENDENCIES];
    for (int i = 0; i < DEPENDENCIES; i++) {
        dependencies[i] = new SimpleServiceDependency();
        dependencies[i].setRequired(true);
        dependencies[i].setCallbacks("add", "remove");
        client.add(dependencies[i]);
    }
    final ConfigurationDependencyImpl confDependency = new ConfigurationDependencyImpl();
    confDependency.setPid("mypid");
    client.add(confDependency);
    // Create Configuration (concurrently).
    // We have to simulate the configuration update, using a component state listener, which will
    // trigger an update thread, but only once the component is started.
    final ComponentStateListener listener = new ComponentStateListener() {

        private volatile Dictionary m_conf;

        public void changed(Component c, ComponentState state) {
            if (state == ComponentState.WAITING_FOR_REQUIRED && m_conf == null) {
                m_conf = new Hashtable();
                m_conf.put("foo", "bar");
                m_threadpool.execute(new Runnable() {

                    public void run() {
                        try {
                            confDependency.updated(m_conf);
                        } catch (ConfigurationException e) {
                            warn("configuration failed", e);
                        }
                    }
                });
            }
        }
    };
    client.add(listener);
    // Start the client (concurrently)
    m_threadpool.execute(new Runnable() {

        public void run() {
            client.start();
            // injected only one the tracker has been opened ...
            for (int i = 0; i < DEPENDENCIES; i++) {
                final SimpleServiceDependency dep = dependencies[i];
                final Event added = new EventImpl(i);
                m_threadpool.execute(new Runnable() {

                    public void run() {
                        dep.add(added);
                    }
                });
            }
        }
    });
    // Ensure that client has been started.
    int expectedStep = 1 + /* conf */
    DEPENDENCIES + 1;
    step.waitForStep(expectedStep, STEP_WAIT);
    Assert.assertEquals(DEPENDENCIES, theClient.getDependencies());
    Assert.assertNotNull(theClient.getConfiguration());
    client.remove(listener);
    // Stop the client and all dependencies concurrently.
    for (int i = 0; i < DEPENDENCIES; i++) {
        final SimpleServiceDependency dep = dependencies[i];
        final Event removed = new EventImpl(i);
        m_threadpool.execute(new Runnable() {

            public void run() {
                dep.remove(removed);
            }
        });
    }
    m_threadpool.execute(new Runnable() {

        public void run() {
            client.stop();
        }
    });
    m_threadpool.execute(new Runnable() {

        public void run() {
            try {
                // simulate a configuration suppression.
                confDependency.updated(null);
            } catch (ConfigurationException e) {
                warn("error while unconfiguring", e);
            }
        }
    });
    // Ensure that client has been stopped, then destroyed, then unbound from all dependencies
    // stop/destroy
    expectedStep += 2;
    // removed all dependencies
    expectedStep += DEPENDENCIES;
    step.waitForStep(expectedStep, STEP_WAIT);
    step.ensure();
    Assert.assertEquals(0, theClient.getDependencies());
    debug("finished one test loop");
    if ((loop + 1) % 100 == 0) {
        long duration = System.currentTimeMillis() - m_timeStamp;
        warn("Performed 100 tests (total=%d) in %d ms.", (loop + 1), duration);
        m_timeStamp = System.currentTimeMillis();
    }
}
Also used : Dictionary(java.util.Dictionary) Hashtable(java.util.Hashtable) ConfigurationDependencyImpl(org.apache.felix.dm.impl.ConfigurationDependencyImpl) ComponentImpl(org.apache.felix.dm.impl.ComponentImpl) ConfigurationException(org.osgi.service.cm.ConfigurationException) Event(org.apache.felix.dm.context.Event) Component(org.apache.felix.dm.Component) ComponentStateListener(org.apache.felix.dm.ComponentStateListener) ComponentState(org.apache.felix.dm.ComponentState)

Example 3 with ComponentStateListener

use of org.apache.felix.dm.ComponentStateListener in project felix by apache.

the class ServiceRaceWithOrderedUnbindTest method doTest.

void doTest(int loop) throws Throwable {
    debug("loop#%d -------------------------", loop);
    final Ensure step = new Ensure(false);
    // Create one client component, which depends on many service dependencies
    final Component client = m_dm.createComponent();
    final Client clientImpl = new Client(step);
    client.setImplementation(clientImpl);
    // Before creating the client, register a component listener to check
    // the client is really started or deactivated.
    ComponentStateListener clientListener = (c, s) -> {
        switch(s) {
            case TRACKING_OPTIONAL:
                step.step(1);
                break;
            case INACTIVE:
                step.step(2);
                break;
            default:
                break;
        }
    };
    client.add(clientListener);
    // Create client service dependencies
    final ServiceDependency[] dependencies = new ServiceDependency[DEPENDENCIES];
    for (int i = 0; i < DEPENDENCIES; i++) {
        final String filter = "(id=loop" + loop + "." + i + ")";
        dependencies[i] = m_dm.createServiceDependency().setService(Dep.class, filter).setRequired(true).setCallbacks("add", "remove");
        client.add(dependencies[i]);
    }
    // Activate the client service dependencies concurrently.
    List<Component> deps = new ArrayList();
    for (int i = 0; i < DEPENDENCIES; i++) {
        Hashtable h = new Hashtable();
        h.put("id", "loop" + loop + "." + i);
        final Component s = m_dm.createComponent().setInterface(Dep.class.getName(), h).setImplementation(new DepImpl());
        deps.add(s);
        schedule(() -> m_dm.add(s));
    }
    // Start the client (concurrently)
    schedule(() -> m_dm.add(client));
    // Ensure that client has been started.
    // client has entered in TRACKING_OPTIONAL state
    step.waitForStep(1, STEP_WAIT);
    Assert.assertEquals(DEPENDENCIES, clientImpl.getDependencies());
    // Make sure threadpool is quiescent, then deactivate all components.
    if (!m_threadPool.awaitQuiescence(5000, TimeUnit.MILLISECONDS)) {
        throw new RuntimeException("Could not start components timely.");
    }
    // Stop all dependencies, and client
    schedule(() -> {
        for (Component dep : deps) {
            final Component dependency = dep;
            m_dm.remove(dependency);
        }
        m_dm.remove(client);
    });
    // Ensure that client has been stopped, then destroyed, then unbound from all dependencies
    // Client entered in INACTIVE state
    step.waitForStep(2, STEP_WAIT);
    step.ensure();
    Assert.assertEquals(0, clientImpl.getDependencies());
    // Make sure threadpool is quiescent before doing next iteration.
    if (!m_threadPool.awaitQuiescence(5000, TimeUnit.MILLISECONDS)) {
        throw new RuntimeException("Could not start components timely.");
    }
    if (super.errorsLogged()) {
        throw new IllegalStateException("Race test interrupted (some error occured, see previous logs)");
    }
    debug("finished one test loop");
    if ((loop + 1) % 100 == 0) {
        long duration = System.currentTimeMillis() - m_timeStamp;
        warn("Performed 100 tests (total=%d) in %d ms.", (loop + 1), duration);
        m_timeStamp = System.currentTimeMillis();
    }
}
Also used : TimeUnit(java.util.concurrent.TimeUnit) List(java.util.List) Component(org.apache.felix.dm.Component) ForkJoinPool(java.util.concurrent.ForkJoinPool) ComponentStateListener(org.apache.felix.dm.ComponentStateListener) Ensure(org.apache.felix.dm.itest.util.Ensure) TestBase(org.apache.felix.dm.itest.util.TestBase) ServiceDependency(org.apache.felix.dm.ServiceDependency) Assert(org.junit.Assert) Hashtable(java.util.Hashtable) ArrayList(java.util.ArrayList) Hashtable(java.util.Hashtable) ArrayList(java.util.ArrayList) ServiceDependency(org.apache.felix.dm.ServiceDependency) Ensure(org.apache.felix.dm.itest.util.Ensure) Component(org.apache.felix.dm.Component) ComponentStateListener(org.apache.felix.dm.ComponentStateListener)

Example 4 with ComponentStateListener

use of org.apache.felix.dm.ComponentStateListener in project felix by apache.

the class FELIX5426_OptionalChangeCallbackNotCalledTest method testCleanupDependenciesDuringComponentRemove.

public void testCleanupDependenciesDuringComponentRemove() {
    DependencyManager m = getDM();
    A aObject = new A();
    Component a = m.createComponent().setImplementation(aObject).add(m.createServiceDependency().setService(B.class).setRequired(false).setCallbacks("add", "change", "remove")).add(m.createServiceDependency().setService(C.class).setRequired(true).setCallbacks("add", "remove"));
    Component b = m.createComponent().setImplementation(new B()).setInterface(B.class.getName(), null);
    Component c = m.createComponent().setImplementation(new C()).setInterface(C.class.getName(), null);
    ComponentStateListener listenerA = (comp, state) -> {
        if (state == ComponentState.STOPPED) {
            Properties properties = new Properties();
            b.setServiceProperties(properties);
        }
    };
    a.add(listenerA);
    m.add(a);
    m.add(b);
    m.add(c);
    // A started
    m_ensure.waitForStep(2, 5000);
    // A is stopping, it should be called in A.remove(C), A.remove(B), but never in A.change(B)
    m.remove(c);
    m_ensure.waitForStep(5, 5000);
    Assert.assertFalse(aObject.bChanged());
}
Also used : Properties(java.util.Properties) Component(org.apache.felix.dm.Component) ComponentState(org.apache.felix.dm.ComponentState) ComponentStateListener(org.apache.felix.dm.ComponentStateListener) Ensure(org.apache.felix.dm.itest.util.Ensure) DependencyManager(org.apache.felix.dm.DependencyManager) TestBase(org.apache.felix.dm.itest.util.TestBase) Assert(org.junit.Assert) Dictionary(java.util.Dictionary) DependencyManager(org.apache.felix.dm.DependencyManager) Component(org.apache.felix.dm.Component) Properties(java.util.Properties) ComponentStateListener(org.apache.felix.dm.ComponentStateListener)

Example 5 with ComponentStateListener

use of org.apache.felix.dm.ComponentStateListener in project felix by apache.

the class FELIX5471_CyclicDependencyTest method testCyclicDependency.

public void testCyclicDependency() throws InterruptedException {
    DependencyManager m = getDM();
    ForkJoinPool tpool = new ForkJoinPool(2);
    try {
        for (int count = 0; count < 1000; count++) {
            m_ensure = new Ensure(false);
            Component a = m.createComponent().setImplementation(new A()).setInterface(A.class.getName(), null).add(m.createServiceDependency().setService(B.class).setRequired(true).setCallbacks("add", "remove"));
            Component b = m.createComponent().setImplementation(new B()).setInterface(B.class.getName(), null).add(m.createServiceDependency().setService(A.class).setRequired(false).setCallbacks("add", "remove"));
            m.add(a);
            m.add(b);
            ComponentStateListener l = (c, s) -> {
                if (s == ComponentState.INACTIVE) {
                    m_ensure.step();
                }
            };
            a.add(l);
            b.add(l);
            // A started, B started
            m_ensure.waitForStep(4, 5000);
            tpool.execute(() -> m.remove(a));
            tpool.execute(() -> m.remove(b));
            // A unbound from  B, stopped and inactive, B unbound from A, stopped and inactive
            m_ensure.waitForStep(10, 5000);
            tpool.awaitQuiescence(5000, TimeUnit.MILLISECONDS);
        }
    } finally {
        tpool.shutdown();
    }
}
Also used : TimeUnit(java.util.concurrent.TimeUnit) Component(org.apache.felix.dm.Component) ComponentState(org.apache.felix.dm.ComponentState) ForkJoinPool(java.util.concurrent.ForkJoinPool) ComponentStateListener(org.apache.felix.dm.ComponentStateListener) Ensure(org.apache.felix.dm.itest.util.Ensure) DependencyManager(org.apache.felix.dm.DependencyManager) TestBase(org.apache.felix.dm.itest.util.TestBase) DependencyManager(org.apache.felix.dm.DependencyManager) Ensure(org.apache.felix.dm.itest.util.Ensure) Component(org.apache.felix.dm.Component) ForkJoinPool(java.util.concurrent.ForkJoinPool) ComponentStateListener(org.apache.felix.dm.ComponentStateListener)

Aggregations

Component (org.apache.felix.dm.Component)6 ComponentStateListener (org.apache.felix.dm.ComponentStateListener)6 ComponentState (org.apache.felix.dm.ComponentState)5 ComponentImpl (org.apache.felix.dm.impl.ComponentImpl)3 Ensure (org.apache.felix.dm.itest.util.Ensure)3 TestBase (org.apache.felix.dm.itest.util.TestBase)3 Dictionary (java.util.Dictionary)2 Hashtable (java.util.Hashtable)2 ForkJoinPool (java.util.concurrent.ForkJoinPool)2 TimeUnit (java.util.concurrent.TimeUnit)2 DependencyManager (org.apache.felix.dm.DependencyManager)2 Assert (org.junit.Assert)2 Test (org.junit.Test)2 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Properties (java.util.Properties)1 Semaphore (java.util.concurrent.Semaphore)1 ServiceDependency (org.apache.felix.dm.ServiceDependency)1 Event (org.apache.felix.dm.context.Event)1 ConfigurationDependencyImpl (org.apache.felix.dm.impl.ConfigurationDependencyImpl)1