X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-distributed-datastore%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Fdatastore%2FDataChangeListenerRegistrationProxy.java;h=33cf8e9c1d292ca46f47cfb3efd9497ed38a63cc;hb=f41c5e6e6f6e10b36b1e4b1992877e38e718c8fb;hp=89cc9695251d18b2efc747b0de2b2882431a8de5;hpb=0d78fea60c4818145e7bd8479427dfc04f0f8145;p=controller.git
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerRegistrationProxy.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerRegistrationProxy.java
index 89cc969525..33cf8e9c1d 100644
--- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerRegistrationProxy.java
+++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerRegistrationProxy.java
@@ -8,30 +8,63 @@
package org.opendaylight.controller.cluster.datastore;
+import akka.actor.ActorRef;
import akka.actor.ActorSelection;
-import org.opendaylight.controller.cluster.datastore.messages.CloseDataChangeListenerRegistration;
+import akka.actor.PoisonPill;
+import akka.dispatch.OnComplete;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.cluster.datastore.exceptions.LocalShardNotFoundException;
+import org.opendaylight.controller.cluster.datastore.messages.CloseDataTreeNotificationListenerRegistration;
+import org.opendaylight.controller.cluster.datastore.messages.RegisterChangeListener;
+import org.opendaylight.controller.cluster.datastore.messages.RegisterDataTreeNotificationListenerReply;
+import org.opendaylight.controller.cluster.datastore.utils.ActorContext;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener;
+import org.opendaylight.controller.md.sal.dom.api.ClusteredDOMDataChangeListener;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import scala.concurrent.Future;
/**
- * ListenerRegistrationProxy acts as a proxy for a ListenerRegistration that was done on a remote shard
+ * ListenerRegistrationProxy acts as a proxy for a ListenerRegistration that was done on a remote shard.
+ *
*
* Registering a DataChangeListener on the Data Store creates a new instance of the ListenerRegistrationProxy
* The ListenerRegistrationProxy talks to a remote ListenerRegistration actor.
- *
*/
+@SuppressWarnings("rawtypes")
public class DataChangeListenerRegistrationProxy implements ListenerRegistration {
- private final ActorSelection listenerRegistrationActor;
- private final AsyncDataChangeListener listener;
- public >>
- DataChangeListenerRegistrationProxy(
- ActorSelection listenerRegistrationActor,
- L listener) {
- this.listenerRegistrationActor = listenerRegistrationActor;
- this.listener = listener;
+ private static final Logger LOG = LoggerFactory.getLogger(DataChangeListenerRegistrationProxy.class);
+
+ private final AsyncDataChangeListener> listener;
+ private final String shardName;
+ private final ActorContext actorContext;
+ private ActorRef dataChangeListenerActor;
+ private volatile ActorSelection listenerRegistrationActor;
+ private boolean closed = false;
+
+ public >>
+ DataChangeListenerRegistrationProxy(final String shardName, final ActorContext actorContext,
+ final L listener) {
+ this.shardName = Preconditions.checkNotNull(shardName);
+ this.actorContext = Preconditions.checkNotNull(actorContext);
+ this.listener = Preconditions.checkNotNull(listener);
+ }
+
+ @VisibleForTesting
+ ActorSelection getListenerRegistrationActor() {
+ return listenerRegistrationActor;
+ }
+
+ @VisibleForTesting
+ ActorRef getDataChangeListenerActor() {
+ return dataChangeListenerActor;
}
@Override
@@ -39,8 +72,89 @@ public class DataChangeListenerRegistrationProxy implements ListenerRegistration
return listener;
}
+ private void setListenerRegistrationActor(final ActorSelection listenerRegistrationActor) {
+ if (listenerRegistrationActor == null) {
+ return;
+ }
+
+ boolean sendCloseMessage = false;
+ synchronized (this) {
+ if (closed) {
+ sendCloseMessage = true;
+ } else {
+ this.listenerRegistrationActor = listenerRegistrationActor;
+ }
+ }
+
+ if (sendCloseMessage) {
+ listenerRegistrationActor.tell(CloseDataTreeNotificationListenerRegistration.getInstance(),
+ ActorRef.noSender());
+ }
+ }
+
+ public void init(final YangInstanceIdentifier path, final AsyncDataBroker.DataChangeScope scope) {
+
+ dataChangeListenerActor = actorContext.getActorSystem().actorOf(
+ DataChangeListener.props(listener, path).withDispatcher(actorContext.getNotificationDispatcherPath()));
+
+ Future findFuture = actorContext.findLocalShardAsync(shardName);
+ findFuture.onComplete(new OnComplete() {
+ @Override
+ public void onComplete(final Throwable failure, final ActorRef shard) {
+ if (failure instanceof LocalShardNotFoundException) {
+ LOG.debug("No local shard found for {} - DataChangeListener {} at path {} "
+ + "cannot be registered", shardName, listener, path);
+ } else if (failure != null) {
+ LOG.error("Failed to find local shard {} - DataChangeListener {} at path {} "
+ + "cannot be registered: {}", shardName, listener, path, failure);
+ } else {
+ doRegistration(shard, path, scope);
+ }
+ }
+ }, actorContext.getClientDispatcher());
+ }
+
+ private void doRegistration(final ActorRef shard, final YangInstanceIdentifier path,
+ final DataChangeScope scope) {
+
+ Future