Author: pderop
Date: Thu Nov 10 12:13:10 2016
New Revision: 1769099
URL: http://svn.apache.org/viewvc?rev=1769099&view=rev
Log:
FELIX-5403: Added STARTING/STARTED/STOPPING/STOPPED events in ComponentState
enum class.
This allows to provide same behavior as in previous dm3.
Modified:
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/ComponentStateListenerTest.java
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentState.java
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentStateListener.java
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ComponentImpl.java
Modified:
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/ComponentStateListenerTest.java
URL:
http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/ComponentStateListenerTest.java?rev=1769099&r1=1769098&r2=1769099&view=diff
==============================================================================
---
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/ComponentStateListenerTest.java
(original)
+++
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/ComponentStateListenerTest.java
Thu Nov 10 12:13:10 2016
@@ -18,15 +18,15 @@
*/
package org.apache.felix.dm.itest.api;
-import org.junit.Assert;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
import org.apache.felix.dm.Component;
import org.apache.felix.dm.ComponentState;
import org.apache.felix.dm.ComponentStateListener;
import org.apache.felix.dm.DependencyManager;
import org.apache.felix.dm.itest.util.Ensure;
import org.apache.felix.dm.itest.util.TestBase;
+import org.junit.Assert;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
/**
* @author <a href="mailto:[email protected]">Felix Project Team</a>
@@ -155,30 +155,27 @@ public class ComponentStateListenerTest
m_ensure.step(9);
}
- public void starting(Component component) {
- debug();
- m_ensure.step(3);
- }
-
- public void started(Component component) {
- debug();
- m_ensure.step(5);
- ServiceReference reference = m_registration.getReference();
- Assert.assertNotNull("Service not yet registered.", reference);
- }
-
- public void stopping(Component component) {
- debug();
- m_ensure.step(6);
- }
-
- public void stopped(Component component) {
- debug();
- m_ensure.step(8);
- }
-
@Override
- public void changed(Component c, ComponentState state) {
+ public void changed(Component c, ComponentState state) {
+ debug();
+ switch (state) {
+ case STARTING:
+ m_ensure.step(3);
+ break;
+ case STARTED:
+ m_ensure.step(5);
+ ServiceReference reference = m_registration.getReference();
+ Assert.assertNotNull("Service not yet registered.",
reference);
+ break;
+ case STOPPING:
+ m_ensure.step(6);
+ break;
+ case STOPPED:
+ m_ensure.step(8);
+ break;
+ default:
+ break;
+ }
}
}
@@ -231,110 +228,28 @@ public class ComponentStateListenerTest
c.remove(this);
}
- public void starting(Component component) {
- debug();
- m_ensure.step(3);
- }
-
- public void started(Component component) {
- debug();
- m_ensure.step(5);
- ServiceReference reference = m_registration.getReference();
- Assert.assertNotNull("Service not yet registered.", reference);
- }
-
- public void stopping(Component component) {
- debug();
- m_ensure.step(6);
- }
-
- public void stopped(Component component) {
- debug();
- m_ensure.step(8);
- }
-
@Override
public void changed(Component c, ComponentState state) {
- // TODO Auto-generated method stub
-
- }
- }
-
- public void testDynamicComponentStateListingLifeCycle2() {
- DependencyManager m = getDM();
- // helper class that ensures certain steps get executed in sequence
- Ensure e = new Ensure();
- // create a simple service component
- Component s =
m.createComponent().setInterface(MyInterface.class.getName(),
null).setImplementation(new DynamicComponentStateListeningInstance2(e));
- // add it, and since it has no dependencies, it should be activated
immediately
- m.add(s);
- // remove it so it gets destroyed
- m.remove(s);
- // ensure we executed all steps inside the component instance
- e.step(10);
- }
-
- static class DynamicComponentStateListeningInstance2 implements
MyInterface, ComponentStateListener {
- volatile ServiceRegistration m_registration;
- private final Ensure m_ensure;
-
- public DynamicComponentStateListeningInstance2(Ensure e) {
- m_ensure = e;
- m_ensure.step(1);
- }
-
- private void debug() {
- StackTraceElement[] stackTrace =
Thread.currentThread().getStackTrace();
- System.out.println("AT: " + stackTrace[2].getClassName() + "." +
stackTrace[2].getMethodName() + "():" + stackTrace[2].getLineNumber());
- }
-
- public void init(Component c) {
- debug();
- m_ensure.step(2);
- }
-
- public void start(Component c) {
- debug();
- m_ensure.step(3);
- c.add(this);
- }
- public void stop(Component c) {
- debug();
- m_ensure.step(7);
- c.remove(this);
- }
-
- public void destroy(Component c) {
- debug();
- m_ensure.step(9);
- }
-
- public void starting(Component component) {
- debug();
- m_ensure.step(4);
- }
-
- public void started(Component component) {
debug();
- m_ensure.step(5);
- ServiceReference reference = m_registration.getReference();
- Assert.assertNotNull("Service not yet registered.", reference);
- }
-
- public void stopping(Component component) {
- debug();
- m_ensure.step(6);
- }
-
- public void stopped(Component component) {
- debug();
- m_ensure.step(8);
- }
-
- @Override
- public void changed(Component c, ComponentState state) {
- // TODO Auto-generated method stub
-
+ switch (state) {
+ case STARTING:
+ m_ensure.step(3);
+ break;
+ case STARTED:
+ m_ensure.step(5);
+ ServiceReference reference = m_registration.getReference();
+ Assert.assertNotNull("Service not yet registered.",
reference);
+ break;
+ case STOPPING:
+ m_ensure.step(6);
+ break;
+ case STOPPED:
+ m_ensure.step(8);
+ break;
+ default:
+ break;
+ }
}
}
+
}
\ No newline at end of file
Modified:
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentState.java
URL:
http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentState.java?rev=1769099&r1=1769098&r2=1769099&view=diff
==============================================================================
---
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentState.java
(original)
+++
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentState.java
Thu Nov 10 12:13:10 2016
@@ -44,5 +44,30 @@ public enum ComponentState {
/**
* The component is active, and is now tracking available optional
dependencies.
*/
- TRACKING_OPTIONAL
+ TRACKING_OPTIONAL,
+
+ /**
+ * The component is starting. At this point, the required
+ * dependencies have been injected, but the service has not been registered
+ * yet.
+ */
+ STARTING,
+
+ /**
+ * The component is started. At this point, the component has been
+ * registered.
+ */
+ STARTED,
+
+ /**
+ * the component is stopping. At this point, the component is still
+ * registered.
+ */
+ STOPPING,
+
+ /**
+ * the component is stopped. At this point, the component has been
+ * unregistered.
+ */
+ STOPPED
}
Modified:
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentStateListener.java
URL:
http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentStateListener.java?rev=1769099&r1=1769098&r2=1769099&view=diff
==============================================================================
---
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentStateListener.java
(original)
+++
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentStateListener.java
Thu Nov 10 12:13:10 2016
@@ -32,38 +32,5 @@ public interface ComponentStateListener
* @param c the component
* @param state the new component state
*/
- public void changed(Component c, ComponentState state);
-
- /**
- * Called when the component is starting. At this point, the required
- * dependencies have been injected, but the service has not been registered
- * yet.
- *
- * @param component the component
- */
- public default void starting(Component component) {}
-
- /**
- * Called when the component is started. At this point, the component has
been
- * registered.
- *
- * @param component the component
- */
- public default void started(Component component) {}
-
- /**
- * Called when the component is stopping. At this point, the component is
still
- * registered.
- *
- * @param component the component
- */
- public default void stopping(Component component) {}
-
- /**
- * Called when the component is stopped. At this point, the component has
been
- * unregistered.
- *
- * @param component the component
- */
- public default void stopped(Component component) {}
+ public void changed(Component c, ComponentState state);
}
Modified:
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ComponentImpl.java
URL:
http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ComponentImpl.java?rev=1769099&r1=1769098&r2=1769099&view=diff
==============================================================================
---
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ComponentImpl.java
(original)
+++
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ComponentImpl.java
Thu Nov 10 12:13:10 2016
@@ -20,6 +20,10 @@ package org.apache.felix.dm.impl;
import static org.apache.felix.dm.ComponentState.INACTIVE;
import static
org.apache.felix.dm.ComponentState.INSTANTIATED_AND_WAITING_FOR_REQUIRED;
+import static org.apache.felix.dm.ComponentState.STARTED;
+import static org.apache.felix.dm.ComponentState.STARTING;
+import static org.apache.felix.dm.ComponentState.STOPPED;
+import static org.apache.felix.dm.ComponentState.STOPPING;
import static org.apache.felix.dm.ComponentState.TRACKING_OPTIONAL;
import static org.apache.felix.dm.ComponentState.WAITING_FOR_REQUIRED;
@@ -43,7 +47,6 @@ import java.util.concurrent.CopyOnWriteA
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
-import java.util.function.BiConsumer;
import org.apache.felix.dm.Component;
import org.apache.felix.dm.ComponentDeclaration;
@@ -277,23 +280,8 @@ public class ComponentImpl implements Co
*/
private boolean m_startCalled;
- // Used to track what state listener callback we have already called
- private int m_stateListener = LISTENER_IDLE;
-
- // We have not yet called any state listener callbacks
- private final static int LISTENER_IDLE = 0;
-
- // We have already called the "starting" state listener callback.
- private final static int LISTENER_STARTING = 1;
-
- // We have already called the "started" state listener callback.
- private final static int LISTENER_STARTED = 2;
-
- // We have already called the "stopping" state listener callback.
- private final static int LISTENER_STOPPING = 3;
-
- // We have already called the "stopped" state listener callback.
- private final static int LISTENER_STOPPED = 4;
+ // Used to track the last state we delivered to any state listeners.
+ private ComponentState m_lastStateDeliveredToListeners =
ComponentState.INACTIVE;
/**
* Default component declaration implementation.
@@ -599,25 +587,27 @@ public class ComponentImpl implements Co
public Component add(ComponentStateListener listener) {
getExecutor().execute(() -> {
m_listeners.add(listener);
- switch (m_stateListener) {
- case LISTENER_STARTING:
+ switch (m_lastStateDeliveredToListeners) {
+ case STARTING:
// this new listener missed the starting cb
- listener.starting(ComponentImpl.this);
+ listener.changed(ComponentImpl.this, STARTING);
break;
- case LISTENER_STARTED:
+ case STARTED:
// this new listener missed the starting/started cb
- listener.starting(ComponentImpl.this);
- listener.started(ComponentImpl.this);
+ listener.changed(ComponentImpl.this, STARTING);
+ listener.changed(ComponentImpl.this, STARTED);
break;
- case LISTENER_STOPPING:
+ case STOPPING:
// this new listener missed the starting/started/stopping cb
- listener.starting(ComponentImpl.this);
- listener.started(ComponentImpl.this);
- listener.stopping(ComponentImpl.this);
+ listener.changed(ComponentImpl.this, STARTING);
+ listener.changed(ComponentImpl.this, STARTED);
+ listener.changed(ComponentImpl.this, STOPPING);
break;
- case LISTENER_STOPPED:
+ case STOPPED:
// no need to call missed listener callbacks
break;
+ default:
+ break;
}
});
return this;
@@ -625,22 +615,7 @@ public class ComponentImpl implements Co
@Override
public Component remove(ComponentStateListener listener) {
- getExecutor().execute(() -> {
- switch (m_stateListener) {
- case LISTENER_STARTING:
- // The listener has been previously called in starting cb;
- // so we should call the listener started cb, before
unregistering it.
- listener.started(ComponentImpl.this);
- break;
-
- case LISTENER_STOPPING:
- // The listener has been previously called in stopping cb;
- // so we should call the listener stopped cb, before
unregistering it.
- listener.stopped(ComponentImpl.this);
- break;
- }
- m_listeners.remove(listener);
- });
+ m_listeners.remove(listener);
return this;
}
@@ -1049,20 +1024,22 @@ public class ComponentImpl implements Co
if (oldState == ComponentState.INSTANTIATED_AND_WAITING_FOR_REQUIRED
&& newState == ComponentState.TRACKING_OPTIONAL) {
invokeAutoConfigInstanceBoundDependencies();
invokeAddRequiredInstanceBoundDependencies();
- notifyListeners(ComponentStateListener::starting,
LISTENER_STARTING);
+ notifyListeners(STARTING);
invokeStart();
invokeAddOptionalDependencies();
registerService();
- notifyListeners(newState, ComponentStateListener::started,
LISTENER_STARTED);
+ notifyListeners(newState);
+ notifyListeners(STARTED);
return true;
}
if (oldState == ComponentState.TRACKING_OPTIONAL && newState ==
ComponentState.INSTANTIATED_AND_WAITING_FOR_REQUIRED) {
- notifyListeners(ComponentStateListener::stopping,
LISTENER_STOPPING);
+ notifyListeners(STOPPING);
unregisterService();
invokeRemoveOptionalDependencies();
invokeStop();
invokeRemoveInstanceBoundDependencies();
- notifyListeners(newState, ComponentStateListener::stopped,
LISTENER_STOPPED);
+ notifyListeners(newState);
+ notifyListeners(STOPPED);
return true;
}
if (oldState == ComponentState.INSTANTIATED_AND_WAITING_FOR_REQUIRED
&& newState == ComponentState.WAITING_FOR_REQUIRED) {
@@ -1569,38 +1546,12 @@ public class ComponentImpl implements Co
}
private void notifyListeners(ComponentState state) {
+ m_lastStateDeliveredToListeners = state;
for (ComponentStateListener l : m_listeners) {
try {
l.changed(this, state);
} catch (Exception e) {
- m_logger.log(Logger.LOG_ERROR, "Exception caught while
invoking component state listener", e);
- }
- }
- }
-
- private void notifyListeners(ComponentState state,
BiConsumer<ComponentStateListener, Component> listenerCallback, int
stateListener) {
- m_stateListener = stateListener;
- for (ComponentStateListener l : m_listeners) {
- try {
- l.changed(this, state);
- } catch (Exception e) {
- m_logger.log(Logger.LOG_ERROR, "Exception caught while
invoking component state listener", e);
- }
- try {
- listenerCallback.accept(l, this);
- } catch (Exception e) {
- m_logger.log(Logger.LOG_ERROR, "Exception caught while
invoking component state listener", e);
- }
- }
- }
-
- private void notifyListeners(BiConsumer<ComponentStateListener,
Component> listenerCallback, int stateListener) {
- m_stateListener = stateListener;
- for (ComponentStateListener l : m_listeners) {
- try {
- listenerCallback.accept(l, this);
- } catch (Exception e) {
- m_logger.log(Logger.LOG_ERROR, "Exception caught while
invoking component state listener", e);
+ m_logger.log(Logger.LOG_ERROR, "Exception
caught while invoking component state listener", e);
}
}
}