From: Jakub Morvay Date: Wed, 7 Nov 2018 18:48:16 +0000 (+0100) Subject: Simplify DTCL registration support classes X-Git-Tag: release/neon~72 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=5dbaf1259ead1904536db204bbc742a3359c1eb1 Simplify DTCL registration support classes 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 --- 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 index 5a09b87da1..0000000000 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/AbstractDataListenerSupport.java +++ /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 - extends LeaderLocalDelegateFactory { - private final Logger log = LoggerFactory.getLogger(getClass()); - - private final Collection> delayedListenerRegistrations = - ConcurrentHashMap.newKeySet(); - private final Collection> delayedListenerOnAllRegistrations = - ConcurrentHashMap.newKeySet(); - private final Collection leaderOnlyListenerActors = ConcurrentHashMap.newKeySet(); - private final Collection allListenerActors = ConcurrentHashMap.newKeySet(); - - protected AbstractDataListenerSupport(Shard shard) { - super(shard); - } - - Collection 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 reg : delayedListenerOnAllRegistrations) { - reg.doRegistration(this); - } - - delayedListenerOnAllRegistrations.clear(); - } - - if (isLeader) { - for (DelayedListenerRegistration 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 delayedReg = - new DelayedListenerRegistration<>(message, registrationActor); - Collection> 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(); -} diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataTreeChangeListenerSupport.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataTreeChangeListenerSupport.java index c7fb05f7e9..348b2aa939 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataTreeChangeListenerSupport.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataTreeChangeListenerSupport.java @@ -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 { +final class DataTreeChangeListenerSupport extends LeaderLocalDelegateFactory { + private static final Logger LOG = LoggerFactory.getLogger(DataTreeChangeListenerSupport.class); + + private final Collection> + delayedDataTreeChangeListenerRegistrations = ConcurrentHashMap.newKeySet(); + private final Collection> + delayedListenerOnAllRegistrations = ConcurrentHashMap.newKeySet(); + private final Collection leaderOnlyListenerActors = ConcurrentHashMap.newKeySet(); + private final Collection 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 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 reg : + delayedListenerOnAllRegistrations) { + reg.doRegistration(this); + } + + delayedListenerOnAllRegistrations.clear(); + } + + if (isLeader) { + for (DelayedDataTreeChangeListenerRegistration 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 delayedReg = + new DelayedDataTreeChangeListenerRegistration<>(message, registrationActor); + final Collection> 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); } } diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DelayedListenerRegistration.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DelayedDataTreeChangeListenerRegistration.java similarity index 68% rename from opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DelayedListenerRegistration.java rename to opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DelayedDataTreeChangeListenerRegistration.java index e1c9f0ba2c..02cfda3609 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DelayedListenerRegistration.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DelayedDataTreeChangeListenerRegistration.java @@ -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 - implements ListenerRegistration { - private final M registrationMessage; +class DelayedDataTreeChangeListenerRegistration implements ListenerRegistration { + 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 support) { + synchronized void doRegistration(final DataTreeChangeListenerSupport support) { if (!closed) { support.doRegistration(registrationMessage, registrationActor); } @@ -39,8 +35,8 @@ class DelayedListenerRegistration