Simplify DTCL registration support classes 02/77602/2
authorJakub Morvay <jmorvay@frinx.io>
Wed, 7 Nov 2018 18:48:16 +0000 (19:48 +0100)
committerRobert Varga <nite@hq.sk>
Thu, 8 Nov 2018 09:31:54 +0000 (09:31 +0000)
Historically, there was support for registration of both
data tree change listeners and data change listeners. Common
infrastructure interfaces, abstract and generic classes were introduced,
since registration of both listener types required similar steps.

Data change listeners were deprecated and removed so there is no need
for this common infrastructure anymore. Get rid of unnecessary
interfaces, abstract classes and type variables. Now they just add
complexity to the code.

Change-Id: Ie2ce510bb5b49b892bcf8e5c562c96ea8345418e
Signed-off-by: Jakub Morvay <jmorvay@frinx.io>
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/AbstractDataListenerSupport.java [deleted file]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataTreeChangeListenerSupport.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DelayedDataTreeChangeListenerRegistration.java [moved from opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DelayedListenerRegistration.java with 68% similarity]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/ListenerRegistrationMessage.java [deleted file]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/RegisterDataTreeChangeListener.java

diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/AbstractDataListenerSupport.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/AbstractDataListenerSupport.java
deleted file mode 100644 (file)
index 5a09b87..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (c) 2015 Brocade Communications 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.cluster.datastore;
-
-import akka.actor.ActorRef;
-import akka.actor.ActorSelection;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.EventListener;
-import java.util.concurrent.ConcurrentHashMap;
-import org.opendaylight.controller.cluster.datastore.actors.DataTreeNotificationListenerRegistrationActor;
-import org.opendaylight.controller.cluster.datastore.messages.EnableNotification;
-import org.opendaylight.controller.cluster.datastore.messages.ListenerRegistrationMessage;
-import org.opendaylight.controller.cluster.datastore.messages.RegisterDataTreeNotificationListenerReply;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-abstract class AbstractDataListenerSupport<L extends EventListener, M extends ListenerRegistrationMessage>
-        extends LeaderLocalDelegateFactory<M> {
-    private final Logger log = LoggerFactory.getLogger(getClass());
-
-    private final Collection<DelayedListenerRegistration<L, M>> delayedListenerRegistrations =
-            ConcurrentHashMap.newKeySet();
-    private final Collection<DelayedListenerRegistration<L, M>> delayedListenerOnAllRegistrations =
-            ConcurrentHashMap.newKeySet();
-    private final Collection<ActorSelection> leaderOnlyListenerActors = ConcurrentHashMap.newKeySet();
-    private final Collection<ActorSelection> allListenerActors = ConcurrentHashMap.newKeySet();
-
-    protected AbstractDataListenerSupport(Shard shard) {
-        super(shard);
-    }
-
-    Collection<ActorSelection> getListenerActors() {
-        return new ArrayList<>(allListenerActors);
-    }
-
-    @Override
-    void onLeadershipChange(boolean isLeader, boolean hasLeader) {
-        log.debug("{}: onLeadershipChange, isLeader: {}, hasLeader : {}", persistenceId(), isLeader, hasLeader);
-
-        final EnableNotification msg = new EnableNotification(isLeader, persistenceId());
-        for (ActorSelection dataChangeListener : leaderOnlyListenerActors) {
-            dataChangeListener.tell(msg, getSelf());
-        }
-
-        if (hasLeader) {
-            for (DelayedListenerRegistration<L, M> reg : delayedListenerOnAllRegistrations) {
-                reg.doRegistration(this);
-            }
-
-            delayedListenerOnAllRegistrations.clear();
-        }
-
-        if (isLeader) {
-            for (DelayedListenerRegistration<L, M> reg : delayedListenerRegistrations) {
-                reg.doRegistration(this);
-            }
-
-            delayedListenerRegistrations.clear();
-        }
-    }
-
-    @Override
-    void onMessage(M message, boolean isLeader, boolean hasLeader) {
-        log.debug("{}: {} for {}, isLeader: {}, hasLeader: {}", persistenceId(), logName(), message,
-                isLeader, hasLeader);
-
-        ActorRef registrationActor = createActor(DataTreeNotificationListenerRegistrationActor.props());
-
-        if (hasLeader && message.isRegisterOnAllInstances() || isLeader) {
-            doRegistration(message, registrationActor);
-        } else {
-            log.debug("{}: Shard is not the leader - delaying registration", persistenceId());
-
-            DelayedListenerRegistration<L, M> delayedReg =
-                    new DelayedListenerRegistration<>(message, registrationActor);
-            Collection<DelayedListenerRegistration<L, M>> delayedRegList;
-            if (message.isRegisterOnAllInstances()) {
-                delayedRegList = delayedListenerOnAllRegistrations;
-            } else {
-                delayedRegList = delayedListenerRegistrations;
-            }
-
-            delayedRegList.add(delayedReg);
-            registrationActor.tell(new DataTreeNotificationListenerRegistrationActor.SetRegistration(
-                    delayedReg, () -> delayedRegList.remove(delayedReg)), ActorRef.noSender());
-        }
-
-        log.debug("{}: {} sending reply, listenerRegistrationPath = {} ", persistenceId(), logName(),
-                registrationActor.path());
-
-        tellSender(new RegisterDataTreeNotificationListenerReply(registrationActor));
-    }
-
-    protected ActorSelection processListenerRegistrationMessage(M message) {
-        final ActorSelection listenerActor = selectActor(message.getListenerActorPath());
-
-        // We have a leader so enable the listener.
-        listenerActor.tell(new EnableNotification(true, persistenceId()), getSelf());
-
-        if (!message.isRegisterOnAllInstances()) {
-            // This is a leader-only registration so store a reference to the listener actor so it can be notified
-            // at a later point if notifications should be enabled or disabled.
-            leaderOnlyListenerActors.add(listenerActor);
-        }
-
-        allListenerActors.add(listenerActor);
-
-        return listenerActor;
-    }
-
-    protected Logger log() {
-        return log;
-    }
-
-    protected void removeListenerActor(ActorSelection listenerActor) {
-        allListenerActors.remove(listenerActor);
-        leaderOnlyListenerActors.remove(listenerActor);
-    }
-
-    abstract void doRegistration(M message, ActorRef registrationActor);
-
-    protected abstract String logName();
-}
index c7fb05f7e920c31b83d870e923636c201ab06d92..348b2aa939efc10617a8f9544a5a738acfdd5345 100644 (file)
@@ -9,24 +9,37 @@ package org.opendaylight.controller.cluster.datastore;
 
 import akka.actor.ActorRef;
 import akka.actor.ActorSelection;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.concurrent.ConcurrentHashMap;
 import org.opendaylight.controller.cluster.datastore.actors.DataTreeNotificationListenerRegistrationActor;
+import org.opendaylight.controller.cluster.datastore.messages.EnableNotification;
 import org.opendaylight.controller.cluster.datastore.messages.RegisterDataTreeChangeListener;
+import org.opendaylight.controller.cluster.datastore.messages.RegisterDataTreeNotificationListenerReply;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-final class DataTreeChangeListenerSupport extends AbstractDataListenerSupport<DOMDataTreeChangeListener,
-        RegisterDataTreeChangeListener> {
+final class DataTreeChangeListenerSupport extends LeaderLocalDelegateFactory<RegisterDataTreeChangeListener> {
+    private static final Logger LOG = LoggerFactory.getLogger(DataTreeChangeListenerSupport.class);
+
+    private final Collection<DelayedDataTreeChangeListenerRegistration<DOMDataTreeChangeListener>>
+            delayedDataTreeChangeListenerRegistrations = ConcurrentHashMap.newKeySet();
+    private final Collection<DelayedDataTreeChangeListenerRegistration<DOMDataTreeChangeListener>>
+            delayedListenerOnAllRegistrations = ConcurrentHashMap.newKeySet();
+    private final Collection<ActorSelection> leaderOnlyListenerActors = ConcurrentHashMap.newKeySet();
+    private final Collection<ActorSelection> allListenerActors = ConcurrentHashMap.newKeySet();
 
     DataTreeChangeListenerSupport(final Shard shard) {
         super(shard);
     }
 
-    @Override
     void doRegistration(final RegisterDataTreeChangeListener message, final ActorRef registrationActor) {
         final ActorSelection listenerActor = processListenerRegistrationMessage(message);
 
-        DOMDataTreeChangeListener listener = new ForwardingDataTreeChangeListener(listenerActor);
+        final DOMDataTreeChangeListener listener = new ForwardingDataTreeChangeListener(listenerActor);
 
-        log().debug("{}: Registering listenerActor {} for path {}", persistenceId(), listenerActor, message.getPath());
+        LOG.debug("{}: Registering listenerActor {} for path {}", persistenceId(), listenerActor, message.getPath());
 
         final ShardDataTree shardDataTree = getShard().getDataStore();
         shardDataTree.registerTreeChangeListener(message.getPath(),
@@ -35,8 +48,88 @@ final class DataTreeChangeListenerSupport extends AbstractDataListenerSupport<DO
                             removeListenerActor(listenerActor)), ActorRef.noSender()));
     }
 
+    Collection<ActorSelection> getListenerActors() {
+        return new ArrayList<>(allListenerActors);
+    }
+
     @Override
-    protected String logName() {
-        return "registerTreeChangeListener";
+    void onLeadershipChange(final boolean isLeader, final boolean hasLeader) {
+        LOG.debug("{}: onLeadershipChange, isLeader: {}, hasLeader : {}", persistenceId(), isLeader, hasLeader);
+
+        final EnableNotification msg = new EnableNotification(isLeader, persistenceId());
+        for (ActorSelection dataChangeListener : leaderOnlyListenerActors) {
+            dataChangeListener.tell(msg, getSelf());
+        }
+
+        if (hasLeader) {
+            for (DelayedDataTreeChangeListenerRegistration<DOMDataTreeChangeListener> reg :
+                    delayedListenerOnAllRegistrations) {
+                reg.doRegistration(this);
+            }
+
+            delayedListenerOnAllRegistrations.clear();
+        }
+
+        if (isLeader) {
+            for (DelayedDataTreeChangeListenerRegistration<DOMDataTreeChangeListener> reg :
+                    delayedDataTreeChangeListenerRegistrations) {
+                reg.doRegistration(this);
+            }
+
+            delayedDataTreeChangeListenerRegistrations.clear();
+        }
+    }
+
+    @Override
+    void onMessage(final RegisterDataTreeChangeListener message, final boolean isLeader, final boolean hasLeader) {
+        LOG.debug("{}: onMessage {}, isLeader: {}, hasLeader: {}", persistenceId(), message, isLeader, hasLeader);
+
+        final ActorRef registrationActor = createActor(DataTreeNotificationListenerRegistrationActor.props());
+
+        if (hasLeader && message.isRegisterOnAllInstances() || isLeader) {
+            doRegistration(message, registrationActor);
+        } else {
+            LOG.debug("{}: Shard does not have a leader - delaying registration", persistenceId());
+
+            final DelayedDataTreeChangeListenerRegistration<DOMDataTreeChangeListener> delayedReg =
+                    new DelayedDataTreeChangeListenerRegistration<>(message, registrationActor);
+            final Collection<DelayedDataTreeChangeListenerRegistration<DOMDataTreeChangeListener>> delayedRegList;
+            if (message.isRegisterOnAllInstances()) {
+                delayedRegList = delayedListenerOnAllRegistrations;
+            } else {
+                delayedRegList = delayedDataTreeChangeListenerRegistrations;
+            }
+
+            delayedRegList.add(delayedReg);
+            registrationActor.tell(new DataTreeNotificationListenerRegistrationActor.SetRegistration(
+                    delayedReg, () -> delayedRegList.remove(delayedReg)), ActorRef.noSender());
+        }
+
+        LOG.debug("{}: sending RegisterDataTreeNotificationListenerReply, listenerRegistrationPath = {} ",
+                persistenceId(), registrationActor.path());
+
+        tellSender(new RegisterDataTreeNotificationListenerReply(registrationActor));
+    }
+
+    private ActorSelection processListenerRegistrationMessage(final RegisterDataTreeChangeListener message) {
+        final ActorSelection listenerActor = selectActor(message.getListenerActorPath());
+
+        // We have a leader so enable the listener.
+        listenerActor.tell(new EnableNotification(true, persistenceId()), getSelf());
+
+        if (!message.isRegisterOnAllInstances()) {
+            // This is a leader-only registration so store a reference to the listener actor so it can be notified
+            // at a later point if notifications should be enabled or disabled.
+            leaderOnlyListenerActors.add(listenerActor);
+        }
+
+        allListenerActors.add(listenerActor);
+
+        return listenerActor;
+    }
+
+    private void removeListenerActor(final ActorSelection listenerActor) {
+        allListenerActors.remove(listenerActor);
+        leaderOnlyListenerActors.remove(listenerActor);
     }
 }
@@ -10,27 +10,23 @@ package org.opendaylight.controller.cluster.datastore;
 import akka.actor.ActorRef;
 import java.util.EventListener;
 import javax.annotation.concurrent.GuardedBy;
-import org.opendaylight.controller.cluster.datastore.messages.ListenerRegistrationMessage;
+import org.opendaylight.controller.cluster.datastore.messages.RegisterDataTreeChangeListener;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 
-class DelayedListenerRegistration<L extends EventListener, M extends ListenerRegistrationMessage>
-        implements ListenerRegistration<L> {
-    private final M registrationMessage;
+class DelayedDataTreeChangeListenerRegistration<L extends EventListener> implements ListenerRegistration<L> {
+    private final RegisterDataTreeChangeListener registrationMessage;
     private final ActorRef registrationActor;
 
     @GuardedBy("this")
     private boolean closed;
 
-    protected DelayedListenerRegistration(M registrationMessage, ActorRef registrationActor) {
+    DelayedDataTreeChangeListenerRegistration(final RegisterDataTreeChangeListener registrationMessage,
+            final ActorRef registrationActor) {
         this.registrationMessage = registrationMessage;
         this.registrationActor = registrationActor;
     }
 
-    M getRegistrationMessage() {
-        return registrationMessage;
-    }
-
-    synchronized void doRegistration(final AbstractDataListenerSupport<L, M> support) {
+    synchronized void doRegistration(final DataTreeChangeListenerSupport support) {
         if (!closed) {
             support.doRegistration(registrationMessage, registrationActor);
         }
@@ -39,8 +35,8 @@ class DelayedListenerRegistration<L extends EventListener, M extends ListenerReg
     @Override
     public L getInstance() {
         // ObjectRegistration annotates this method as @Nonnull but we could return null if the delegate is not set yet.
-        // In reality, we do not and should not ever call this method on DelayedListenerRegistration instances anyway
-        // but, since we have to provide an implementation to satisfy the interface, we throw
+        // In reality, we do not and should not ever call this method on DelayedDataTreeChangeListenerRegistration
+        // instances anyway but, since we have to provide an implementation to satisfy the interface, we throw
         // UnsupportedOperationException to honor the API contract of not returning null and to avoid a FindBugs error
         // for possibly returning null.
         throw new UnsupportedOperationException(
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/ListenerRegistrationMessage.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/ListenerRegistrationMessage.java
deleted file mode 100644 (file)
index 3f016a4..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (c) 2015 Brocade Communications 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.cluster.datastore.messages;
-
-import akka.actor.ActorPath;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-
-public interface ListenerRegistrationMessage {
-    YangInstanceIdentifier getPath();
-
-    boolean isRegisterOnAllInstances();
-
-    ActorPath getListenerActorPath();
-}
index e091b5bd0ffcb8c99759c53c2628facf0201dfa1..f790d1d4b2ada70a7938ed5316850d6ac22ae95c 100644 (file)
@@ -21,7 +21,7 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
  * Request a {@link org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeListener} registration be made on the
  * shard leader.
  */
-public final class RegisterDataTreeChangeListener implements Externalizable, ListenerRegistrationMessage {
+public final class RegisterDataTreeChangeListener implements Externalizable {
     private static final long serialVersionUID = 1L;
     private ActorRef dataTreeChangeListenerPath;
     private YangInstanceIdentifier path;
@@ -38,17 +38,14 @@ public final class RegisterDataTreeChangeListener implements Externalizable, Lis
         this.registerOnAllInstances = registerOnAllInstances;
     }
 
-    @Override
     public YangInstanceIdentifier getPath() {
         return path;
     }
 
-    @Override
     public ActorPath getListenerActorPath() {
         return dataTreeChangeListenerPath.path();
     }
 
-    @Override
     public boolean isRegisterOnAllInstances() {
         return registerOnAllInstances;
     }