BUG-3183: Extend notification publisher API 93/21093/2
authorMichal Rehak <mirehak@cisco.com>
Tue, 12 May 2015 08:36:26 +0000 (10:36 +0200)
committerGerrit Code Review <gerrit@opendaylight.org>
Tue, 26 May 2015 13:40:02 +0000 (13:40 +0000)
 - offer methods of notificationPublishService now return ListenableFuture
 - added exception for notification rejected outcome

Change-Id: Iff17e1edd754d49e6c53f97e357c34f5eac6a8ef
Signed-off-by: Michal Rehak <mirehak@cisco.com>
(cherry picked from commit 38c80b0fc0c559aabd0a8dce59dd99deab1c3418)

opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/NotificationPublishService.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/NotificationRejectedException.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDOMNotificationPublishServiceAdapter.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/ForwardedNotificationAdapterTest.java

index 87e37ffed1dbf0f1e9bc2fdb7c366427b314078c..5ec51269b738df3e7625133773a2d72cf1af7705 100644 (file)
@@ -7,6 +7,8 @@
  */
 package org.opendaylight.controller.md.sal.binding.api;
 
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
 import java.util.concurrent.TimeUnit;
 import org.opendaylight.yangtools.yang.binding.Notification;
 
@@ -26,6 +28,13 @@ import org.opendaylight.yangtools.yang.binding.Notification;
  * notification has or has not been seen.
  */
 public interface NotificationPublishService extends BindingService {
+
+    /**
+     * Well-known value indicating that the binding-aware implementation is currently not
+     * able to accept a notification.
+     */
+    ListenableFuture<Object> REJECTED = Futures.immediateFailedFuture(new NotificationRejectedException("Rejected due to resource constraints."));
+
     /**
      * Publishes a notification to subscribed listeners. This initiates
      * the process of sending the notification, but delivery to the
@@ -47,14 +56,16 @@ public interface NotificationPublishService extends BindingService {
      * listeners can happen asynchronously, potentially after a call to
      * this method returns.
      *
-     * This method is guaranteed not to block.
+     * Still guaranteed not to block. Returns Listenable Future which will complete once.
      *
      * @param notification
      *            the notification to publish.
-     * @return true if the notification was accepted for processing, false otherwise
+     * @return A listenable future which will report completion when the service has finished
+     * propagating the notification to its immediate registrants, or {@value #REJECTED} if resource
+     * constraints prevent
      * @throws NullPointerException if the notification is null
      */
-    boolean offerNotification(Notification notification);
+    ListenableFuture<? extends Object> offerNotification(Notification notification);
 
     /**
      * Publishes a notification to subscribed listeners. This initiates
@@ -68,11 +79,14 @@ public interface NotificationPublishService extends BindingService {
      * @param timeout how long to wait before giving up, in units of unit
      * @param unit a TimeUnit determining how to interpret the
      *             timeout parameter
-     * @return true if the notification was accepted for processing, false otherwise
+     * @return A listenable future which will report completion when the service has finished
+     * propagating the notification to its immediate registrants, or {@value #REJECTED} if resource
+     * constraints prevent
      * @throws InterruptedException if interrupted while waiting
      * @throws NullPointerException if the notification or unit is null
      * @throws IllegalArgumentException if timeout is negative.
      */
-    boolean offerNotification(Notification notification, int timeout, TimeUnit unit)
-        throws InterruptedException;
+    ListenableFuture<? extends Object> offerNotification(Notification notification, int timeout, TimeUnit unit)
+            throws InterruptedException;
+
 }
diff --git a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/NotificationRejectedException.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/NotificationRejectedException.java
new file mode 100644 (file)
index 0000000..4423d79
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * 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.controller.md.sal.binding.api;
+
+/**
+ * <p/>
+ * This exception indicates that given notification can not be processed by corresponding mechanism.
+ * More info can be provided in message.
+ * <p/>
+ * <p>
+ * Expected use: {@link NotificationPublishService}
+ * </p>
+ */
+public class NotificationRejectedException extends Exception {
+
+    private static final long serialVersionUID = 3722954527834860394L;
+
+    public NotificationRejectedException(String message) {
+        super(message);
+    }
+}
index 084f423807df24f004c3aa1a6dd6c3424905d1b7..1fe81ea3f497d6511293582e19feb237cb10bad4 100644 (file)
@@ -52,16 +52,19 @@ public class BindingDOMNotificationPublishServiceAdapter implements Notification
     }
 
     @Override
-    public boolean offerNotification(final Notification notification) {
-        final ListenableFuture<?> listenableFuture = domPublishService.offerNotification(toDomNotification(notification));
-        return !DOMNotificationPublishService.REJECTED.equals(listenableFuture);
+    public ListenableFuture<? extends Object> offerNotification(final Notification notification) {
+        ListenableFuture<?> offerResult = domPublishService.offerNotification(toDomNotification(notification));
+        return DOMNotificationPublishService.REJECTED.equals(offerResult)
+                ? NotificationPublishService.REJECTED
+                : offerResult;
     }
 
     @Override
-    public boolean offerNotification(final Notification notification, final int timeout, final TimeUnit unit) throws InterruptedException {
-        final ListenableFuture<?> listenableFuture =
-                domPublishService.offerNotification(toDomNotification(notification), timeout, unit);
-        return !DOMNotificationPublishService.REJECTED.equals(listenableFuture);
+    public ListenableFuture<? extends Object> offerNotification(final Notification notification, final int timeout, final TimeUnit unit) throws InterruptedException {
+        ListenableFuture<?> offerResult = domPublishService.offerNotification(toDomNotification(notification), timeout, unit);
+        return DOMNotificationPublishService.REJECTED.equals(offerResult)
+                ? NotificationPublishService.REJECTED
+                : offerResult;
     }
 
     private DOMNotification toDomNotification(final Notification notification) {
index c2cdc0caaaddff9e813e7f8f22457ea104b21844..cf7ad16ad3afdc7c0a340cb646ecda9d2ae8ef25 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.controller.md.sal.binding.impl.test;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
 import static org.junit.Assert.assertTrue;
 
 import com.google.common.collect.ImmutableList;
@@ -15,8 +16,12 @@ import com.google.common.collect.ImmutableSet;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import org.junit.Assert;
 import org.junit.Test;
+import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
 import org.opendaylight.controller.md.sal.binding.test.AbstractNotificationBrokerTest;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.OpendaylightMdsalListTestListener;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.TwoLevelListChanged;
@@ -26,9 +31,13 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controll
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
 import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class ForwardedNotificationAdapterTest extends AbstractNotificationBrokerTest {
 
+    private static final Logger LOG = LoggerFactory.getLogger(ForwardedNotificationAdapterTest.class);
+
     @Override
     protected Iterable<YangModuleInfo> getModuleInfos() throws Exception {
         return ImmutableSet.of(BindingReflections.getModuleInfo(TwoLevelListChanged.class));
@@ -66,7 +75,12 @@ public class ForwardedNotificationAdapterTest extends AbstractNotificationBroker
         final TestNotifListener testNotifListener = new TestNotifListener(latch);
         final ListenerRegistration<TestNotifListener> listenerRegistration = getNotificationService()
                 .registerNotificationListener(testNotifListener);
-        assertTrue(getNotificationPublishService().offerNotification(testData));
+        try {
+            getNotificationPublishService().offerNotification(testData).get(1, TimeUnit.SECONDS);
+        } catch (ExecutionException | TimeoutException e) {
+            LOG.error("Notification delivery failed", e);
+            Assert.fail("notification should be delivered");
+        }
 
         latch.await();
         assertTrue(testNotifListener.getReceivedNotifications().size() == 1);
@@ -83,7 +97,8 @@ public class ForwardedNotificationAdapterTest extends AbstractNotificationBroker
         final TestNotifListener testNotifListener = new TestNotifListener(latch);
         final ListenerRegistration<TestNotifListener> listenerRegistration = getNotificationService()
                 .registerNotificationListener(testNotifListener);
-        assertTrue(getNotificationPublishService().offerNotification(testData, 5, TimeUnit.SECONDS));
+        assertNotSame(NotificationPublishService.REJECTED,
+                getNotificationPublishService().offerNotification(testData, 5, TimeUnit.SECONDS));
 
         latch.await();
         assertTrue(testNotifListener.getReceivedNotifications().size() == 1);