BUG 1735 Registering a data change listener should be asynchronous
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / datastore / DataChangeListener.java
index ba09d0402530921667915eae11103302cfcfb2ea..f1c0df4c3ad2a336a6aa8edc7282aa399f160c13 100644 (file)
@@ -9,22 +9,75 @@
 package org.opendaylight.controller.cluster.datastore;
 
 import akka.actor.Props;
-import akka.actor.UntypedActor;
 import akka.japi.Creator;
 
-public class DataChangeListener extends UntypedActor {
-    @Override public void onReceive(Object message) throws Exception {
-        throw new UnsupportedOperationException("onReceive");
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.cluster.common.actor.AbstractUntypedActor;
+
+import org.opendaylight.controller.cluster.datastore.messages.DataChanged;
+import org.opendaylight.controller.cluster.datastore.messages.DataChangedReply;
+import org.opendaylight.controller.cluster.datastore.messages.EnableNotification;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+public class DataChangeListener extends AbstractUntypedActor {
+    private final AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>> listener;
+    private volatile boolean notificationsEnabled = false;
+
+    public DataChangeListener(AsyncDataChangeListener<YangInstanceIdentifier,
+                                                      NormalizedNode<?, ?>> listener) {
+        this.listener = Preconditions.checkNotNull(listener, "listener should not be null");
+    }
+
+    @Override public void handleReceive(Object message) throws Exception {
+        if(message instanceof DataChanged){
+            dataChanged(message);
+        } else if(message instanceof EnableNotification){
+            enableNotification((EnableNotification) message);
+        }
+    }
+
+    private void enableNotification(EnableNotification message) {
+        notificationsEnabled = message.isEnabled();
     }
 
-    public static Props props() {
-        return Props.create(new Creator<DataChangeListener>() {
-            @Override
-            public DataChangeListener create() throws Exception {
-                return new DataChangeListener();
-            }
+    private void dataChanged(Object message) {
+
+        // Do nothing if notifications are not enabled
+        if(!notificationsEnabled){
+            return;
+        }
+
+        DataChanged reply = (DataChanged) message;
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>>
+            change = reply.getChange();
+        this.listener.onDataChanged(change);
+
+        if(getSender() != null){
+            getSender().tell(new DataChangedReply(), getSelf());
+        }
+    }
+
+    public static Props props(final AsyncDataChangeListener<YangInstanceIdentifier,
+                                                            NormalizedNode<?, ?>> listener) {
+        return Props.create(new DataChangeListenerCreator(listener));
+    }
+
+    private static class DataChangeListenerCreator implements Creator<DataChangeListener> {
+        private static final long serialVersionUID = 1L;
+
+        final AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>> listener;
 
-        });
+        DataChangeListenerCreator(
+                AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>> listener) {
+            this.listener = listener;
+        }
 
+        @Override
+        public DataChangeListener create() throws Exception {
+            return new DataChangeListener(listener);
+        }
     }
 }