From: Robert Varga Date: Fri, 24 Jun 2022 12:59:30 +0000 (+0200) Subject: Add registerNotificationListeners() X-Git-Tag: v10.0.0~4 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=b3a6f6aa3ca13dcd9d232e3879d6d03ce5687097;p=mdsal.git Add registerNotificationListeners() We have a use case where we really want to perform a bulk registration of multiple listeners. Add the corresponding method and implement it in DOMNotificationRouter. JIRA: MDSAL-701 Change-Id: I57e16f4f1044a96ee06dafb003436d84ca47c829 Signed-off-by: Robert Varga --- diff --git a/dom/mdsal-dom-api/src/main/java/module-info.java b/dom/mdsal-dom-api/src/main/java/module-info.java index 35d55a2b93..de37454ad8 100644 --- a/dom/mdsal-dom-api/src/main/java/module-info.java +++ b/dom/mdsal-dom-api/src/main/java/module-info.java @@ -9,6 +9,7 @@ module org.opendaylight.mdsal.dom.api { exports org.opendaylight.mdsal.dom.api; exports org.opendaylight.mdsal.dom.api.query; + requires transitive com.google.common; requires transitive org.opendaylight.yangtools.yang.common; requires transitive org.opendaylight.yangtools.yang.data.api; requires transitive org.opendaylight.yangtools.yang.data.tree.api; diff --git a/dom/mdsal-dom-api/src/main/java/org/opendaylight/mdsal/dom/api/DOMNotificationService.java b/dom/mdsal-dom-api/src/main/java/org/opendaylight/mdsal/dom/api/DOMNotificationService.java index 7d0bd53859..283215a7e5 100644 --- a/dom/mdsal-dom-api/src/main/java/org/opendaylight/mdsal/dom/api/DOMNotificationService.java +++ b/dom/mdsal-dom-api/src/main/java/org/opendaylight/mdsal/dom/api/DOMNotificationService.java @@ -9,8 +9,10 @@ package org.opendaylight.mdsal.dom.api; import java.util.Arrays; import java.util.Collection; +import java.util.Map; import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute; /** @@ -19,7 +21,7 @@ import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absol public interface DOMNotificationService extends DOMService { /** * Register a {@link DOMNotificationListener} to receive a set of notifications. As with other - * ListenerRegistration-based interfaces, registering an instance multiple times results in + * {@link ListenerRegistration}-based interfaces, registering an instance multiple times results in * notifications being delivered for each registration. * * @param listener Notification instance to register @@ -36,7 +38,7 @@ public interface DOMNotificationService extends DOMService { /** * Register a {@link DOMNotificationListener} to receive a set of notifications. As with other - * ListenerRegistration-based interfaces, registering an instance multiple times results in + * {@link ListenerRegistration}-based interfaces, registering an instance multiple times results in * notifications being delivered for each registration. * * @param listener Notification instance to register @@ -52,4 +54,14 @@ public interface DOMNotificationService extends DOMService { registerNotificationListener(@NonNull final T listener, final Absolute... types) { return registerNotificationListener(listener, Arrays.asList(types)); } + + /** + * Register a number of {@link DOMNotificationListener}s to receive some notification notifications. As with other + * {@link Registration}-based interfaces, registering an instance multiple times results in + * notifications being delivered for each registration. + * + * @param typeToListener Specification of which types to listen to with which listeners + * @throws NullPointerException if {@code typeToListener} is {@code null} + */ + @NonNull Registration registerNotificationListeners(@NonNull Map typeToListener); } diff --git a/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/DOMNotificationRouter.java b/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/DOMNotificationRouter.java index 35db4b41f5..5e73988830 100644 --- a/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/DOMNotificationRouter.java +++ b/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/DOMNotificationRouter.java @@ -18,7 +18,9 @@ import com.google.common.util.concurrent.MoreExecutors; import com.google.common.util.concurrent.ThreadFactoryBuilder; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -35,7 +37,9 @@ import org.opendaylight.mdsal.dom.api.DOMNotificationService; import org.opendaylight.mdsal.dom.spi.DOMNotificationSubscriptionListener; import org.opendaylight.mdsal.dom.spi.DOMNotificationSubscriptionListenerRegistry; import org.opendaylight.yangtools.concepts.AbstractListenerRegistration; +import org.opendaylight.yangtools.concepts.AbstractRegistration; import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.util.ListenerRegistry; import org.opendaylight.yangtools.util.concurrent.EqualityQueuedNotificationManager; import org.opendaylight.yangtools.util.concurrent.FluentFutures; @@ -73,8 +77,14 @@ public class DOMNotificationRouter implements AutoCloseable, DOMNotificationPubl } @VisibleForTesting - final class Reg extends AbstractListenerRegistration { - private Reg(final @NonNull T listener) { + abstract static sealed class Reg extends AbstractListenerRegistration { + Reg(final @NonNull T listener) { + super(listener); + } + } + + private final class SingleReg extends Reg { + SingleReg(final @NonNull T listener) { super(listener); } @@ -84,6 +94,17 @@ public class DOMNotificationRouter implements AutoCloseable, DOMNotificationPubl } } + private static final class ComponentReg extends Reg { + ComponentReg(final @NonNull DOMNotificationListener listener) { + super(listener); + } + + @Override + protected void removeRegistration() { + // No-op + } + } + private static final Logger LOG = LoggerFactory.getLogger(DOMNotificationRouter.class); private static final ListenableFuture NO_LISTENERS = FluentFutures.immediateNullFluentFuture(); @@ -124,13 +145,13 @@ public class DOMNotificationRouter implements AutoCloseable, DOMNotificationPubl @Override public synchronized ListenerRegistration registerNotificationListener( final T listener, final Collection types) { - final var reg = new Reg<>(listener); + final var reg = new SingleReg<>(listener); if (!types.isEmpty()) { final var b = ImmutableMultimap.>builder(); b.putAll(listeners); - for (final Absolute t : types) { + for (var t : types) { b.put(t, reg); } @@ -140,10 +161,35 @@ public class DOMNotificationRouter implements AutoCloseable, DOMNotificationPubl return reg; } - private synchronized void removeRegistration(final Reg reg) { + @Override + public synchronized Registration registerNotificationListeners( + final Map typeToListener) { + final var b = ImmutableMultimap.>builder(); + b.putAll(listeners); + + final var tmp = new HashMap(); + for (var e : typeToListener.entrySet()) { + b.put(e.getKey(), tmp.computeIfAbsent(e.getValue(), ComponentReg::new)); + } + + final var regs = List.copyOf(tmp.values()); + return new AbstractRegistration() { + @Override + protected void removeRegistration() { + regs.forEach(ComponentReg::close); + removeRegistrations(regs); + } + }; + } + + private synchronized void removeRegistration(final SingleReg reg) { replaceListeners(ImmutableMultimap.copyOf(Multimaps.filterValues(listeners, input -> input != reg))); } + private synchronized void removeRegistrations(final List regs) { + replaceListeners(ImmutableMultimap.copyOf(Multimaps.filterValues(listeners, input -> !regs.contains(input)))); + } + /** * Swaps registered listeners and triggers notification update. * diff --git a/dom/mdsal-dom-spi/src/main/java/org/opendaylight/mdsal/dom/spi/ForwardingDOMNotificationService.java b/dom/mdsal-dom-spi/src/main/java/org/opendaylight/mdsal/dom/spi/ForwardingDOMNotificationService.java index 079cb186cc..e044787b37 100644 --- a/dom/mdsal-dom-spi/src/main/java/org/opendaylight/mdsal/dom/spi/ForwardingDOMNotificationService.java +++ b/dom/mdsal-dom-spi/src/main/java/org/opendaylight/mdsal/dom/spi/ForwardingDOMNotificationService.java @@ -9,9 +9,11 @@ package org.opendaylight.mdsal.dom.spi; import com.google.common.collect.ForwardingObject; import java.util.Collection; +import java.util.Map; import org.opendaylight.mdsal.dom.api.DOMNotificationListener; import org.opendaylight.mdsal.dom.api.DOMNotificationService; import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute; /** @@ -33,4 +35,9 @@ public abstract class ForwardingDOMNotificationService extends ForwardingObject final Absolute... types) { return delegate().registerNotificationListener(listener, types); } + + @Override + public Registration registerNotificationListeners(final Map typeToListener) { + return delegate().registerNotificationListeners(typeToListener); + } }