X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-binding-broker%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Fbinding%2Fimpl%2FNotificationBrokerImpl.java;h=49c24f9dc59ac64bc88b1c8df3041dfde05d510f;hp=d3b68002c3a64402a23d7fb20ae557165e4f9e72;hb=16dad33d563a80c98aa261bafc7cc3cf472fffb0;hpb=c0e4638d5f1f29249b3fe74b64e7d85dd388c489 diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.java index d3b68002c3..49c24f9dc5 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.java @@ -7,9 +7,6 @@ */ package org.opendaylight.controller.sal.binding.impl; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; import java.util.Set; import java.util.concurrent.ExecutorService; @@ -17,80 +14,44 @@ import org.opendaylight.controller.sal.binding.api.NotificationListener; import org.opendaylight.controller.sal.binding.api.NotificationProviderService; import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder; import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory.NotificationInvoker; +import org.opendaylight.yangtools.concepts.AbstractListenerRegistration; import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.concepts.util.ListenerRegistry; import org.opendaylight.yangtools.yang.binding.Notification; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Preconditions; -import com.google.common.base.Predicate; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Iterables; -import com.google.common.collect.Multimap; -import com.google.common.collect.Multimaps; public class NotificationBrokerImpl implements NotificationProviderService, AutoCloseable { private static final Logger LOG = LoggerFactory.getLogger(NotificationBrokerImpl.class); private final ListenerRegistry interestListeners = ListenerRegistry.create(); + private final NotificationListenerMap listeners = new NotificationListenerMap(); + private final ExecutorService executor; - private final Multimap, NotificationListener> listeners = - Multimaps.synchronizedSetMultimap(HashMultimap., NotificationListener>create()); - private ExecutorService executor; - - @Deprecated public NotificationBrokerImpl(final ExecutorService executor) { - this.setExecutor(executor); - } - - public void setExecutor(final ExecutorService executor) { this.executor = Preconditions.checkNotNull(executor); } - public Iterable> getNotificationTypes(final Notification notification) { - final Class[] ifaces = notification.getClass().getInterfaces(); - return Iterables.filter(Arrays.asList(ifaces), new Predicate>() { - @Override - public boolean apply(final Class input) { - if (Notification.class.equals(input)) { - return false; - } - return Notification.class.isAssignableFrom(input); - } - }); - } - @Override public void publish(final Notification notification) { - this.publish(notification, executor); + publish(notification, executor); } @Override public void publish(final Notification notification, final ExecutorService service) { - Iterable> listenerToNotify = Collections.emptySet(); - for (final Class type : getNotificationTypes(notification)) { - listenerToNotify = Iterables.concat(listenerToNotify, listeners.get(((Class) type))); - } - - final Set tasks = new HashSet<>(); - for (NotificationListener l : listenerToNotify) { - tasks.add(new NotifyTask(l, notification)); - } - - for (final NotifyTask task : tasks) { - service.submit(task); + for (NotificationListenerRegistration r : listeners.listenersFor(notification)) { + service.submit(new NotifyTask(r, notification)); } } - @Override - public Registration> registerNotificationListener(final Class notificationType, final NotificationListener listener) { - final GenericNotificationRegistration reg = new GenericNotificationRegistration(notificationType, listener, this); - this.listeners.put(notificationType, listener); - this.announceNotificationSubscription(notificationType); - return reg; + private final void addRegistrations(final NotificationListenerRegistration... registrations) { + listeners.addRegistrations(registrations); + for (NotificationListenerRegistration reg : registrations) { + announceNotificationSubscription(reg.getType()); + } } private void announceNotificationSubscription(final Class notification) { @@ -105,37 +66,62 @@ public class NotificationBrokerImpl implements NotificationProviderService, Auto } @Override - public Registration registerNotificationListener(final org.opendaylight.yangtools.yang.binding.NotificationListener listener) { - final NotificationInvoker invoker = SingletonHolder.INVOKER_FACTORY.invokerFor(listener); - for (final Class notifyType : invoker.getSupportedNotifications()) { - listeners.put(notifyType, invoker.getInvocationProxy()); - announceNotificationSubscription(notifyType); + public ListenerRegistration registerInterestListener(final NotificationInterestListener interestListener) { + final ListenerRegistration registration = this.interestListeners.register(interestListener); + for (final Class notification : listeners.getKnownTypes()) { + interestListener.onNotificationSubscribtion(notification); } - - return new GeneratedListenerRegistration(listener, invoker, this); + return registration; } - protected boolean unregisterListener(final GenericNotificationRegistration reg) { - return listeners.remove(reg.getType(), reg.getInstance()); + @Override + public NotificationListenerRegistration registerNotificationListener(final Class notificationType, final NotificationListener listener) { + final NotificationListenerRegistration reg = new AbstractNotificationListenerRegistration(notificationType, listener) { + @Override + protected void removeRegistration() { + listeners.removeRegistrations(this); + } + }; + + addRegistrations(reg); + return reg; } - protected void unregisterListener(final GeneratedListenerRegistration reg) { - final NotificationInvoker invoker = reg.getInvoker(); - for (final Class notifyType : invoker.getSupportedNotifications()) { - this.listeners.remove(notifyType, invoker.getInvocationProxy()); + @Override + public ListenerRegistration registerNotificationListener(final org.opendaylight.yangtools.yang.binding.NotificationListener listener) { + final NotificationInvoker invoker = SingletonHolder.INVOKER_FACTORY.invokerFor(listener); + final Set> types = invoker.getSupportedNotifications(); + final NotificationListenerRegistration[] regs = new NotificationListenerRegistration[types.size()]; + + // Populate the registrations... + int i = 0; + for (Class type : types) { + regs[i] = new AggregatedNotificationListenerRegistration(type, invoker.getInvocationProxy(), regs) { + @Override + protected void removeRegistration() { + // Nothing to do, will be cleaned up by parent (below) + } + }; + ++i; } + + // ... now put them to use ... + addRegistrations(regs); + + // ... finally return the parent registration + return new AbstractListenerRegistration(listener) { + @Override + protected void removeRegistration() { + listeners.removeRegistrations(regs); + for (ListenerRegistration reg : regs) { + reg.close(); + } + } + }; } @Override public void close() { } - @Override - public ListenerRegistration registerInterestListener(final NotificationInterestListener interestListener) { - final ListenerRegistration registration = this.interestListeners.register(interestListener); - for (final Class notification : listeners.keySet()) { - interestListener.onNotificationSubscribtion(notification); - } - return registration; - } }