X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-distributed-datastore%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Fdatastore%2FDataTreeChangeListenerSupport.java;h=9a44b47e7e9257222804ed46c1e08ccaabdbf322;hp=afce4df546febce2dd122b1eb431896855503ca8;hb=a3cecfd01d0ef8922530924e3ee9684eb03ee5d6;hpb=66d39ecc3effd52c96c7a772a46612008e34fbc9 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 afce4df546..9a44b47e7e 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,86 +9,93 @@ package org.opendaylight.controller.cluster.datastore; import akka.actor.ActorRef; import akka.actor.ActorSelection; -import com.google.common.base.Preconditions; +import com.google.common.base.Optional; +import com.google.common.collect.Sets; import java.util.ArrayList; import java.util.Collection; +import java.util.Map.Entry; +import java.util.Set; import org.opendaylight.controller.cluster.datastore.messages.EnableNotification; import org.opendaylight.controller.cluster.datastore.messages.RegisterDataTreeChangeListener; import org.opendaylight.controller.cluster.datastore.messages.RegisterDataTreeChangeListenerReply; import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeListener; import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate; -final class DataTreeChangeListenerSupport extends LeaderLocalDelegateFactory> { - private static final Logger LOG = LoggerFactory.getLogger(DataTreeChangeListenerSupport.class); - private final ArrayList delayedRegistrations = new ArrayList<>(); - private final Collection actors = new ArrayList<>(); - private final Shard shard; +final class DataTreeChangeListenerSupport extends AbstractDataListenerSupport> { - DataTreeChangeListenerSupport(final Shard shard) { - this.shard = Preconditions.checkNotNull(shard); - } - - @Override - void onLeadershipChange(final boolean isLeader) { - if (isLeader) { - for (DelayedDataTreeListenerRegistration reg : delayedRegistrations) { - reg.createDelegate(this); - } - delayedRegistrations.clear(); - delayedRegistrations.trimToSize(); - } + private final Set listenerActors = Sets.newConcurrentHashSet(); - final EnableNotification msg = new EnableNotification(isLeader); - for (ActorSelection dataChangeListener : actors) { - dataChangeListener.tell(msg, shard.getSelf()); - } + DataTreeChangeListenerSupport(final Shard shard) { + super(shard); } - @Override - void onMessage(final RegisterDataTreeChangeListener registerTreeChangeListener, final boolean isLeader) { - LOG.debug("{}: registerTreeChangeListener for {}, leader: {}", shard.persistenceId(), registerTreeChangeListener.getPath(), isLeader); - - final ListenerRegistration registration; - if (!isLeader) { - LOG.debug("{}: Shard is not the leader - delaying registration", shard.persistenceId()); - - DelayedDataTreeListenerRegistration delayedReg = - new DelayedDataTreeListenerRegistration(registerTreeChangeListener); - delayedRegistrations.add(delayedReg); - registration = delayedReg; - } else { - registration = createDelegate(registerTreeChangeListener); - } - - ActorRef listenerRegistration = shard.getContext().actorOf( - DataTreeChangeListenerRegistrationActor.props(registration)); - - LOG.debug("{}: registerDataChangeListener sending reply, listenerRegistrationPath = {} ", - shard.persistenceId(), listenerRegistration.path()); - - shard.getSender().tell(new RegisterDataTreeChangeListenerReply(listenerRegistration), shard.getSelf()); + Collection getListenerActors() { + return new ArrayList<>(listenerActors); } @Override - ListenerRegistration createDelegate(final RegisterDataTreeChangeListener message) { - ActorSelection dataChangeListenerPath = shard.getContext().system().actorSelection( - message.getDataTreeChangeListenerPath().path()); + ListenerRegistration createDelegate( + final RegisterDataTreeChangeListener message) { + final ActorSelection dataChangeListenerPath = selectActor(message.getDataTreeChangeListenerPath()); // Notify the listener if notifications should be enabled or not // If this shard is the leader then it will enable notifications else // it will not - dataChangeListenerPath.tell(new EnableNotification(true), shard.getSelf()); + dataChangeListenerPath.tell(new EnableNotification(true), getSelf()); // Now store a reference to the data change listener so it can be notified // at a later point if notifications should be enabled or disabled - actors.add(dataChangeListenerPath); + if (!message.isRegisterOnAllInstances()) { + addListenerActor(dataChangeListenerPath); + } DOMDataTreeChangeListener listener = new ForwardingDataTreeChangeListener(dataChangeListenerPath); - LOG.debug("{}: Registering for path {}", shard.persistenceId(), message.getPath()); + log().debug("{}: Registering for path {}", persistenceId(), message.getPath()); + + Entry, Optional> regEntry = + getShard().getDataStore().registerTreeChangeListener(message.getPath(), listener); + + getShard().getDataStore().notifyOfInitialData(message.getPath(), + regEntry.getKey().getInstance(), regEntry.getValue()); - return shard.getDataStore().registerTreeChangeListener(message.getPath(), listener); + listenerActors.add(dataChangeListenerPath); + final ListenerRegistration delegate = regEntry.getKey(); + return new ListenerRegistration() { + @Override + public DOMDataTreeChangeListener getInstance() { + return delegate.getInstance(); + } + + @Override + public void close() { + listenerActors.remove(dataChangeListenerPath); + delegate.close(); + } + }; + } + + @Override + protected DelayedDataTreeListenerRegistration newDelayedListenerRegistration( + RegisterDataTreeChangeListener message) { + return new DelayedDataTreeListenerRegistration(message); + } + + @Override + protected ActorRef newRegistrationActor(ListenerRegistration registration) { + return createActor(DataTreeChangeListenerRegistrationActor.props(registration)); + } + + @Override + protected Object newRegistrationReplyMessage(ActorRef registrationActor) { + return new RegisterDataTreeChangeListenerReply(registrationActor); + } + + @Override + protected String logName() { + return "registerTreeChangeListener"; } }