Binding2 runtime - API #7 23/58323/4
authorMartin Ciglan <martin.ciglan@pantheon.tech>
Wed, 24 May 2017 13:44:29 +0000 (15:44 +0200)
committerMartin Ciglan <martin.ciglan@pantheon.tech>
Tue, 6 Jun 2017 18:25:23 +0000 (18:25 +0000)
- NotificationPublishService & its relatives
- test coverage for classes
- Javadocs provided

Change-Id: I888f72924d8fe38e76f0990fec34b040824439c6
Signed-off-by: Martin Ciglan <martin.ciglan@pantheon.tech>
(cherry picked from commit 82540750ebcfb2887733e953cad0205e3fcd16ee)

binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/NotificationPublishService.java [new file with mode: 0644]
binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/NotificationRejectedException.java [new file with mode: 0644]
binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/NotificationService.java [new file with mode: 0644]
binding2/mdsal-binding2-api/src/test/java/org/opendaylight/mdsal/binding/javav2/api/NotificationRejectedExceptionTest.java [new file with mode: 0644]

diff --git a/binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/NotificationPublishService.java b/binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/NotificationPublishService.java
new file mode 100644 (file)
index 0000000..eb5d8c2
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.binding.javav2.api;
+
+import com.google.common.annotations.Beta;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.TimeUnit;
+import org.opendaylight.mdsal.binding.javav2.spec.base.InstanceIdentifier;
+import org.opendaylight.mdsal.binding.javav2.spec.base.KeyedInstanceIdentifier;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Notification;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
+
+/**
+ * A {@link NotificationService} which also allows its users to submit YANG-modeled notifications for delivery.
+ *
+ * <p>
+ * There are three methods of submission, following the patters from {@link java.util.concurrent.BlockingQueue}:
+ *
+ * <p>
+ * - {@link #putNotification(org.opendaylight.mdsal.binding.javav2.spec.base.Notification)}, which may block
+ * indefinitely if the implementation cannot allocate resources to accept the notification,
+ * - {@link #offerNotification(org.opendaylight.mdsal.binding.javav2.spec.base.Notification)}, which does not block if
+ * face of resource starvation,
+ * - {@link #offerNotification(org.opendaylight.mdsal.binding.javav2.spec.base.Notification, int, TimeUnit)}, which may
+ * block for specified time if resources are thin.
+ *
+ * <p>
+ * Every method has two alternatives for YANG 1.1 notifications tied to container or list node.
+ *
+ *<p>
+ * The actual delivery to listeners is asynchronous and implementation-specific.
+ * Users of this interface should not make any assumptions as to whether the
+ * notification has or has not been seen.
+ */
+
+@Beta
+public interface NotificationPublishService {
+
+    ListenableFuture<Object> REJECTED = Futures.immediateFailedFuture(
+        new NotificationRejectedException("Rejected due to resource constraints."));
+
+    void putNotification(Notification notification) throws InterruptedException;
+
+    ListenableFuture<?> offerNotification(Notification notification);
+
+    ListenableFuture<?> offerNotification(Notification notification, int timeout, TimeUnit unit)
+        throws InterruptedException;
+
+
+    <T extends TreeNode> void putContainerNotification(Notification notification, InstanceIdentifier<T> ii)
+        throws InterruptedException;
+
+    <T extends TreeNode> ListenableFuture<?> offerContainerNotification(Notification notification,
+        InstanceIdentifier<T> ii);
+
+    <T extends TreeNode> ListenableFuture<?> offerContainerNotification(Notification notification, int timeout,
+        TimeUnit unit, InstanceIdentifier<T> ii) throws InterruptedException;
+
+
+    <T extends TreeNode, K> void putListNotification(Notification notification, KeyedInstanceIdentifier<T, K> kii)
+        throws InterruptedException;
+
+    <T extends TreeNode, K> ListenableFuture<?> offerListNotification(Notification notification,
+        KeyedInstanceIdentifier<T, K> kii);
+
+    <T extends TreeNode, K> ListenableFuture<?> offerListNotification(Notification notification, int timeout,
+        TimeUnit unit, KeyedInstanceIdentifier<T, K> kii) throws InterruptedException;
+}
diff --git a/binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/NotificationRejectedException.java b/binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/NotificationRejectedException.java
new file mode 100644 (file)
index 0000000..90bd6ff
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.binding.javav2.api;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * This exception indicates that given notification can not be processed by corresponding mechanism.
+ * More info can be provided in message.
+ *
+ * <p>
+ * Expected use: {@link NotificationPublishService}
+ */
+@Beta
+public class NotificationRejectedException extends Exception {
+
+    private static final long serialVersionUID = 1L;
+
+    public NotificationRejectedException(final String message) {
+        super(message);
+    }
+
+    public NotificationRejectedException(final String message, final Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/NotificationService.java b/binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/NotificationService.java
new file mode 100644 (file)
index 0000000..08768e3
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.binding.javav2.api;
+
+import com.google.common.annotations.Beta;
+import org.opendaylight.mdsal.binding.javav2.spec.runtime.NotificationListener;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+
+/**
+ * Notification broker which allows clients to subscribe for and publish YANG-modeled notifications.
+ *
+ *<p>
+ * Each YANG module which defines notifications results in a generated interface
+ * <code>{ModuleName}Listener</code> which handles all the notifications defined in the YANG model.
+ * Each notification type translates to a specific method of the form
+ * <code>on{NotificationType}</code> on the generated interface. The generated interface also
+ * extends the {@link org.opendaylight.mdsal.binding.javav2.spec.runtime.NotificationListener} interface and
+ * implementations are registered using
+ * {@link #registerNotificationListener(org.opendaylight.mdsal.binding.javav2.spec.runtime.NotificationListener)}
+ * method.
+ *
+ * <b>Dispatch Listener Example</b>
+ *
+ * <p>
+ * Lets assume we have following YANG model:
+ *
+ * <pre>
+ * module example {
+ *      ...
+ *
+ *      notification start {
+ *          ...
+ *      }
+ *
+ *      notification stop {
+ *           ...
+ *      }
+ * }
+ * </pre>
+ *
+ * <p>
+ * The generated interface will be:
+ *
+ * <pre>
+ * public interface ExampleListener extends NotificationListener {
+ *     void onStart(Start notification);
+ *
+ *     void onStop(Stop notification);
+ * }
+ * </pre>
+ *
+ * <p>
+ * The following defines an implementation of the generated interface:
+ *
+ * <pre>
+ * public class MyExampleListener implements ExampleListener {
+ *     public void onStart(Start notification) {
+ *         // do something
+ *     }
+ *
+ *     public void onStop(Stop notification) {
+ *         // do something
+ *     }
+ * }
+ * </pre>
+ *
+ * <p>
+ * The implementation is registered as follows:
+ *
+ * <pre>
+ * MyExampleListener listener = new MyExampleListener();
+ * ListenerRegistration&lt;NotificationListener&gt; reg = service.registerNotificationListener(listener);
+ * </pre>
+ *
+ * <p>
+ * The <code>onStart</code> method will be invoked when someone publishes a <code>Start</code>
+ * notification and the <code>onStop</code> method will be invoked when someone publishes a
+ * <code>Stop</code> notification.
+ *
+ * <p>
+ * YANG 1.1: in case of notification tied to data note (container, list):
+ *
+ * <pre>
+ * module example {
+ *      ...
+ *
+ *      container cont {
+ *          notification notify {
+ *              ...
+ *          }
+ *      ...
+ *      }
+ * }
+ * </pre>
+ *
+ * <p>
+ * The generated interface will be:
+ *
+ * <pre>
+ * public interface ExampleListener extends NotificationListener {
+ *     void onContNotify(Notify notification);
+ *
+ * }
+ * </pre>
+ */
+@Beta
+public interface NotificationService extends BindingService {
+
+    /**
+     * Registers a listener which implements a YANG-generated notification interface derived from
+     * {@link NotificationListener}. The listener is registered for all notifications present in
+     * the implemented interface.
+     *
+     * <p>
+     * @param listener the listener implementation that will receive notifications.
+     * @param <T> listener type
+     * @return a {@link ListenerRegistration} instance that should be used to unregister the listener
+     *         by invoking the {@link ListenerRegistration#close()} method when no longer needed.
+     */
+    <T extends NotificationListener> ListenerRegistration<T> registerNotificationListener(T listener);
+}
diff --git a/binding2/mdsal-binding2-api/src/test/java/org/opendaylight/mdsal/binding/javav2/api/NotificationRejectedExceptionTest.java b/binding2/mdsal-binding2-api/src/test/java/org/opendaylight/mdsal/binding/javav2/api/NotificationRejectedExceptionTest.java
new file mode 100644 (file)
index 0000000..58d971a
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.binding.javav2.api;
+
+import org.junit.Test;
+
+public class NotificationRejectedExceptionTest {
+
+    @Test(expected = NotificationRejectedException.class)
+    public void constructWithCauseTest() throws Exception {
+        throw new NotificationRejectedException("test", new Throwable());
+    }
+
+    @Test(expected = NotificationRejectedException.class)
+    public void constructTest() throws Exception {
+        throw new NotificationRejectedException("test");
+    }
+}