You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by li...@apache.org on 2010/04/08 16:27:10 UTC
svn commit: r931955 - in /incubator/aries/trunk/subsystem/subsystem-core: ./
src/main/java/org/apache/aries/subsystem/core/internal/
Author: linsun
Date: Thu Apr 8 14:27:09 2010
New Revision: 931955
URL: http://svn.apache.org/viewvc?rev=931955&view=rev
Log:
ARIES-278 Provide subsystem event dispatcher to dispatch events to Subsystem listener, based on blueprint event dispatcher without event admin notification
Added:
incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemEventDispatcher.java (with props)
Modified:
incubator/aries/trunk/subsystem/subsystem-core/pom.xml
incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Activator.java
incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemAdminImpl.java
Modified: incubator/aries/trunk/subsystem/subsystem-core/pom.xml
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-core/pom.xml?rev=931955&r1=931954&r2=931955&view=diff
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-core/pom.xml (original)
+++ incubator/aries/trunk/subsystem/subsystem-core/pom.xml Thu Apr 8 14:27:09 2010
@@ -60,6 +60,15 @@
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.utils</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
Modified: incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Activator.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Activator.java?rev=931955&r1=931954&r2=931955&view=diff
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Activator.java (original)
+++ incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Activator.java Thu Apr 8 14:27:09 2010
@@ -39,9 +39,12 @@ public class Activator implements Bundle
private BundleContext context;
private List<ServiceRegistration> registrations = new ArrayList<ServiceRegistration>();
+ private static SubsystemEventDispatcher eventDispatcher;
public void start(BundleContext context) throws Exception {
this.context = context;
+ eventDispatcher = new SubsystemEventDispatcher(context);
+
register(SubsystemAdmin.class, new SubsystemAdminFactory(), null);
register(ResourceResolver.class,
new NoOpResolver(),
@@ -83,7 +86,7 @@ public class Activator implements Bundle
SubsystemAdminImpl admin = admins.get(systemBundleContext);
long ref = 0;
if (admin == null) {
- admin = new SubsystemAdminImpl(systemBundleContext);
+ admin = new SubsystemAdminImpl(systemBundleContext, eventDispatcher);
admins.put(systemBundleContext, admin);
} else {
ref = references.get(admin);
Modified: incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemAdminImpl.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemAdminImpl.java?rev=931955&r1=931954&r2=931955&view=diff
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemAdminImpl.java (original)
+++ incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemAdminImpl.java Thu Apr 8 14:27:09 2010
@@ -48,9 +48,11 @@ public class SubsystemAdminImpl implemen
final Map<Long, Subsystem> subsystems = new HashMap<Long, Subsystem>();
final ServiceTracker compositeAdminTracker;
final ServiceTracker resourceResolverTracker;
+ final SubsystemEventDispatcher eventDispatcher;
- public SubsystemAdminImpl(BundleContext context) {
+ public SubsystemAdminImpl(BundleContext context, SubsystemEventDispatcher eventDispatcher) {
this.context = context;
+ this.eventDispatcher = eventDispatcher;
this.compositeAdminTracker = new ServiceTracker(context, CompositeAdmin.class.getName(), null);
this.compositeAdminTracker.open();
this.resourceResolverTracker = new ServiceTracker(context, ResourceResolver.class.getName(), null);
Added: incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemEventDispatcher.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemEventDispatcher.java?rev=931955&view=auto
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemEventDispatcher.java (added)
+++ incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemEventDispatcher.java Thu Apr 8 14:27:09 2010
@@ -0,0 +1,152 @@
+package org.apache.aries.subsystem.core.internal;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.aries.subsystem.Subsystem;
+import org.apache.aries.subsystem.SubsystemEvent;
+import org.apache.aries.subsystem.SubsystemListener;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.SynchronousBundleListener;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * this event dispatcher dispatches subsystem events to subsystem listeners.
+ *
+ */
+public class SubsystemEventDispatcher implements SubsystemListener, SynchronousBundleListener {
+
+ private static final Logger LOGGER = LoggerFactory
+ .getLogger(SubsystemEventDispatcher.class);
+ private final Set<SubsystemListener> listeners = new CopyOnWriteArraySet<SubsystemListener>();
+ private final Map<Subsystem, SubsystemEvent> states = new ConcurrentHashMap<Subsystem, SubsystemEvent>();
+ private final ExecutorService executor = Executors
+ .newSingleThreadExecutor();
+ private final ServiceTracker containerListenerTracker;
+
+ SubsystemEventDispatcher(final BundleContext bundleContext) {
+
+ assert bundleContext != null;
+
+ this.containerListenerTracker = new ServiceTracker(bundleContext,
+ SubsystemListener.class.getName(),
+ new ServiceTrackerCustomizer() {
+ public Object addingService(ServiceReference reference) {
+ SubsystemListener listener = (SubsystemListener) bundleContext
+ .getService(reference);
+
+ synchronized (listeners) {
+ sendInitialEvents(listener);
+ listeners.add(listener);
+ }
+
+ return listener;
+ }
+
+ public void modifiedService(ServiceReference reference,
+ Object service) {
+ }
+
+ public void removedService(ServiceReference reference,
+ Object service) {
+ listeners.remove(service);
+ bundleContext.ungetService(reference);
+ }
+ });
+ this.containerListenerTracker.open();
+ }
+
+ private void sendInitialEvents(SubsystemListener listener) {
+ for (Map.Entry<Subsystem, SubsystemEvent> entry : states.entrySet()) {
+ try {
+ callListener(listener, entry.getValue());
+ } catch (RejectedExecutionException ree) {
+ LOGGER.warn("Executor shut down", ree);
+ break;
+ }
+ }
+ }
+
+ private void callListeners(SubsystemEvent event) {
+ for (final SubsystemListener listener : listeners) {
+ try {
+ callListener(listener, event);
+ } catch (RejectedExecutionException ree) {
+ LOGGER.warn("Executor shut down", ree);
+ break;
+ }
+ }
+ }
+
+ private void callListener(final SubsystemListener listener,
+ final SubsystemEvent event) throws RejectedExecutionException {
+ try {
+ executor.invokeAny(Collections
+ .<Callable<Void>> singleton(new Callable<Void>() {
+ public Void call() throws Exception {
+ listener.subsystemEvent(event);
+ return null;
+ }
+ }), 60L, TimeUnit.SECONDS);
+ } catch (InterruptedException ie) {
+ LOGGER.warn("Thread interrupted", ie);
+ Thread.currentThread().interrupt();
+ } catch (TimeoutException te) {
+ LOGGER.warn("Listener timed out, will be ignored", te);
+ listeners.remove(listener);
+ } catch (ExecutionException ee) {
+ LOGGER.warn("Listener caused an exception, will be ignored", ee);
+ listeners.remove(listener);
+ }
+ }
+
+ public void subsystemEvent(SubsystemEvent event) {
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("Sending Subsystem event {} for subsystem {}",
+ toString(event), event.getSubsystem().getSymbolicName());
+ }
+
+ synchronized (listeners) {
+ callListeners(event);
+ states.put(event.getSubsystem(), event);
+ }
+ }
+
+ @SuppressWarnings( { "ThrowableResultOfMethodCallIgnored" })
+ private static String toString(SubsystemEvent event) {
+ return "SubsystemEvent[subsystem=" + event.getSubsystem().getScope()
+ + " type=" + event.getType() + "]";
+ }
+
+ void destroy() {
+ executor.shutdown();
+ // wait for the queued tasks to execute
+ try {
+ executor.awaitTermination(60, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ containerListenerTracker.close();
+ }
+
+ public void bundleChanged(BundleEvent event) {
+ if (BundleEvent.STOPPING == event.getType()) {
+ states.remove(event.getBundle());
+ }
+ }
+}
Propchange: incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemEventDispatcher.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemEventDispatcher.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemEventDispatcher.java
------------------------------------------------------------------------------
svn:mime-type = text/plain