Refactor DOMNotificationSubscriptionListener(Registry) 02/109202/2
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 7 Dec 2023 14:09:48 +0000 (15:09 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 7 Dec 2023 14:40:26 +0000 (15:40 +0100)
This interface wants to really be a DOMNotificationPublish.Extension.
Rename it and move it to mdsal.dom.api.

JIRA: MDSAL-481
Change-Id: I2b376726b49e64925e259dd4aed584fd3aa47e0c
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
dom/mdsal-dom-api/src/main/java/org/opendaylight/mdsal/dom/api/DOMNotificationPublishDemandExtension.java [new file with mode: 0644]
dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/DOMNotificationRouter.java
dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/DOMNotificationRouterTest.java
dom/mdsal-dom-spi/src/main/java/org/opendaylight/mdsal/dom/spi/DOMNotificationSubscriptionListener.java [deleted file]
dom/mdsal-dom-spi/src/main/java/org/opendaylight/mdsal/dom/spi/DOMNotificationSubscriptionListenerRegistry.java [deleted file]

diff --git a/dom/mdsal-dom-api/src/main/java/org/opendaylight/mdsal/dom/api/DOMNotificationPublishDemandExtension.java b/dom/mdsal-dom-api/src/main/java/org/opendaylight/mdsal/dom/api/DOMNotificationPublishDemandExtension.java
new file mode 100644 (file)
index 0000000..3d9fc0c
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.mdsal.dom.api;
+
+import com.google.common.annotations.Beta;
+import com.google.common.collect.ImmutableSet;
+import java.util.EventListener;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
+
+/**
+ * A {@link DOMNotificationPublishService.Extension} providing a view into which {@link DOMNotification}s the extended
+ * {@link DOMNotificationPublishService} is interested in receiving. This is typically driven by listener registrations
+ * in the {@link DOMNotificationService} consuming published notifications.
+ */
+@Beta
+@NonNullByDefault
+public interface DOMNotificationPublishDemandExtension extends DOMNotificationPublishService.Extension {
+    /**
+     * Register a new {@link DemandListener}.
+     *
+     * @param listener the listener to register
+     * @return A {@link Registration}
+     * @throws NullPointerException if {@code listener} is {@code null}
+     */
+    Registration registerDemandListener(DemandListener listener);
+
+    /**
+     * Listener for changes in demand for {@link DOMNotification} types. Changes are communnicated via
+     * {@link #onDemandUpdated(ImmutableSet)}, which reports the delta between last reported and current state.
+     */
+    interface DemandListener extends EventListener {
+        /**
+         * Update the view of what {@link DOMNotification}s are in demand.
+         *
+         * @param neededTypes currently-needed notification types
+         */
+        void onDemandUpdated(ImmutableSet<Absolute> neededTypes);
+    }
+}
index 32f218c62462444a33f417121fe3c170478c06de..1fe8bc6437907a67fd98d180060e3f12d631b733 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.mdsal.dom.broker;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Multimaps;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
@@ -20,20 +21,20 @@ 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;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 import javax.annotation.PreDestroy;
 import javax.inject.Inject;
+import javax.inject.Singleton;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.mdsal.dom.api.DOMNotification;
 import org.opendaylight.mdsal.dom.api.DOMNotificationListener;
+import org.opendaylight.mdsal.dom.api.DOMNotificationPublishDemandExtension;
+import org.opendaylight.mdsal.dom.api.DOMNotificationPublishDemandExtension.DemandListener;
 import org.opendaylight.mdsal.dom.api.DOMNotificationPublishService;
 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;
@@ -60,12 +61,11 @@ import org.slf4j.LoggerFactory;
  * Internal implementation one by using a {@link QueuedNotificationManager}.
  *</p>
  */
-@Component(configurationPid = "org.opendaylight.mdsal.dom.notification", service = {
-    DOMNotificationRouter.class, DOMNotificationSubscriptionListenerRegistry.class
-})
+@Singleton
+@Component(configurationPid = "org.opendaylight.mdsal.dom.notification", service = DOMNotificationRouter.class)
 @Designate(ocd = DOMNotificationRouter.Config.class)
 // Non-final for testing
-public class DOMNotificationRouter implements DOMNotificationSubscriptionListenerRegistry, AutoCloseable {
+public class DOMNotificationRouter implements AutoCloseable {
     @ObjectClassDefinition()
     public @interface Config {
         @AttributeDefinition(name = "notification-queue-depth")
@@ -101,7 +101,12 @@ public class DOMNotificationRouter implements DOMNotificationSubscriptionListene
         }
     }
 
-    private final class PublishFacade implements DOMNotificationPublishService {
+    private final class PublishFacade implements DOMNotificationPublishService, DOMNotificationPublishDemandExtension {
+        @Override
+        public List<Extension> supportedExtensions() {
+            return List.of(this);
+        }
+
         @Override
         public ListenableFuture<? extends Object> putNotification(final DOMNotification notification)
                 throws InterruptedException {
@@ -140,6 +145,13 @@ public class DOMNotificationRouter implements DOMNotificationSubscriptionListene
                 return DOMNotificationPublishService.REJECTED;
             }
         }
+
+        @Override
+        public Registration registerDemandListener(final DemandListener listener) {
+            final var initialTypes = listeners.keySet();
+            executor.execute(() -> listener.onDemandUpdated(initialTypes));
+            return demandListeners.register(listener);
+        }
     }
 
     private final class SubscribeFacade implements DOMNotificationService {
@@ -192,8 +204,7 @@ public class DOMNotificationRouter implements DOMNotificationSubscriptionListene
     private static final Logger LOG = LoggerFactory.getLogger(DOMNotificationRouter.class);
     private static final @NonNull ListenableFuture<?> NO_LISTENERS = Futures.immediateFuture(Empty.value());
 
-    private final ListenerRegistry<DOMNotificationSubscriptionListener> subscriptionListeners =
-            ListenerRegistry.create();
+    private final ListenerRegistry<DemandListener> demandListeners = ListenerRegistry.create();
     private final EqualityQueuedNotificationManager<AbstractListenerRegistration<? extends DOMNotificationListener>,
                 DOMNotificationRouterEvent> queueNotificationManager;
     private final @NonNull DOMNotificationPublishService notificationPublishService = new PublishFacade();
@@ -250,27 +261,19 @@ public class DOMNotificationRouter implements DOMNotificationSubscriptionListene
     }
 
     @SuppressWarnings("checkstyle:IllegalCatch")
-    private void notifyListenerTypesChanged(final Set<Absolute> typesAfter) {
-        final var listenersAfter = subscriptionListeners.streamListeners().collect(ImmutableList.toImmutableList());
+    private void notifyListenerTypesChanged(final @NonNull ImmutableSet<Absolute> typesAfter) {
+        final var listenersAfter = demandListeners.streamListeners().collect(ImmutableList.toImmutableList());
         executor.execute(() -> {
-            for (var subListener : listenersAfter) {
+            for (var listener : listenersAfter) {
                 try {
-                    subListener.onSubscriptionChanged(typesAfter);
+                    listener.onDemandUpdated(typesAfter);
                 } catch (final Exception e) {
-                    LOG.warn("Uncaught exception during invoking listener {}", subListener, e);
+                    LOG.warn("Uncaught exception during invoking listener {}", listener, e);
                 }
             }
         });
     }
 
-    @Override
-    public <L extends DOMNotificationSubscriptionListener> ListenerRegistration<L> registerSubscriptionListener(
-            final L listener) {
-        final var initialTypes = listeners.keySet();
-        executor.execute(() -> listener.onSubscriptionChanged(initialTypes));
-        return subscriptionListeners.register(listener);
-    }
-
     @VisibleForTesting
     @NonNull ListenableFuture<? extends Object> putNotificationImpl(final DOMNotification notification)
             throws InterruptedException {
@@ -315,8 +318,8 @@ public class DOMNotificationRouter implements DOMNotificationSubscriptionListene
     }
 
     @VisibleForTesting
-    ListenerRegistry<DOMNotificationSubscriptionListener> subscriptionListeners() {
-        return subscriptionListeners;
+    ListenerRegistry<DemandListener> demandListeners() {
+        return demandListeners;
     }
 
     private static void deliverEvents(final AbstractListenerRegistration<? extends DOMNotificationListener> reg,
index 133b1a154207506fa3b969904525084324dc6370..3413e61a6af7132f41e88aff08e7dc6eb135a1d0 100644 (file)
@@ -30,8 +30,9 @@ import java.util.concurrent.TimeUnit;
 import org.junit.Test;
 import org.opendaylight.mdsal.dom.api.DOMNotification;
 import org.opendaylight.mdsal.dom.api.DOMNotificationListener;
+import org.opendaylight.mdsal.dom.api.DOMNotificationPublishDemandExtension;
+import org.opendaylight.mdsal.dom.api.DOMNotificationPublishDemandExtension.DemandListener;
 import org.opendaylight.mdsal.dom.api.DOMNotificationPublishService;
-import org.opendaylight.mdsal.dom.spi.DOMNotificationSubscriptionListener;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
 
@@ -68,14 +69,16 @@ public class DOMNotificationRouterTest {
     @SuppressWarnings("checkstyle:IllegalCatch")
     @Test
     public void complexTest() throws Exception {
-        final var domNotificationSubscriptionListener = mock(DOMNotificationSubscriptionListener.class);
-        doNothing().when(domNotificationSubscriptionListener).onSubscriptionChanged(any());
+        final var demandListener = mock(DemandListener.class);
+        doNothing().when(demandListener).onDemandUpdated(any());
 
         final var latch = new CountDownLatch(1);
         final var domNotificationListener = new TestListener(latch);
         final var domNotificationRouter = new DOMNotificationRouter(1024);
         final var notifService = domNotificationRouter.notificationService();
         final var notifPubService = domNotificationRouter.notificationPublishService();
+        final var demandExt = notifPubService.extension(DOMNotificationPublishDemandExtension.class);
+        assertNotNull(demandExt);
 
         var listeners = domNotificationRouter.listeners();
 
@@ -89,14 +92,11 @@ public class DOMNotificationRouterTest {
 
         assertFalse(listeners.isEmpty());
 
-        var subscriptionListeners = domNotificationRouter.subscriptionListeners();
+        assertEquals(0, domNotificationRouter.demandListeners().streamListeners().count());
 
-        assertEquals(0, subscriptionListeners.streamListeners().count());
-        assertNotNull(domNotificationRouter.registerSubscriptionListener(domNotificationSubscriptionListener));
+        assertNotNull(demandExt.registerDemandListener(demandListener));
 
-        subscriptionListeners = domNotificationRouter.subscriptionListeners();
-        assertSame(domNotificationSubscriptionListener,
-            subscriptionListeners.streamListeners().findAny().orElseThrow());
+        assertSame(demandListener, domNotificationRouter.demandListeners().streamListeners().findAny().orElseThrow());
 
         final var domNotification = mock(DOMNotification.class);
         doReturn("test").when(domNotification).toString();
diff --git a/dom/mdsal-dom-spi/src/main/java/org/opendaylight/mdsal/dom/spi/DOMNotificationSubscriptionListener.java b/dom/mdsal-dom-spi/src/main/java/org/opendaylight/mdsal/dom/spi/DOMNotificationSubscriptionListener.java
deleted file mode 100644 (file)
index ee919cb..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.mdsal.dom.spi;
-
-import com.google.common.annotations.Beta;
-import java.util.EventListener;
-import java.util.Set;
-import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
-
-/**
- * Listener which is notified when subscriptions changes and provides set of notification types for which currently
- * subscriptions are in place.
- */
-@Beta
-public interface DOMNotificationSubscriptionListener extends EventListener {
-    /**
-     * Invoked when notification subscription changed.
-     *
-     * @param currentTypes Set of notification types for which listeners are registered.
-     */
-    void onSubscriptionChanged(Set<Absolute> currentTypes);
-}
diff --git a/dom/mdsal-dom-spi/src/main/java/org/opendaylight/mdsal/dom/spi/DOMNotificationSubscriptionListenerRegistry.java b/dom/mdsal-dom-spi/src/main/java/org/opendaylight/mdsal/dom/spi/DOMNotificationSubscriptionListenerRegistry.java
deleted file mode 100644 (file)
index ddce026..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.mdsal.dom.spi;
-
-import com.google.common.annotations.Beta;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-
-/**
- * Registry of {@link DOMNotificationSubscriptionListener}
- * which listens for changes in notification types.
- *
- */
-@Beta
-public interface DOMNotificationSubscriptionListenerRegistry  {
-
-    <L extends DOMNotificationSubscriptionListener> ListenerRegistration<L> registerSubscriptionListener(L listener);
-}