X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;ds=sidebyside;f=opendaylight%2Fmd-sal%2Fsal-distributed-datastore%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Fdatastore%2FDataChangeListenerSupport.java;h=2e26e6ee36d170d4bb0d3da3ae3d276d8f62305c;hb=583f30d1c7a8199b401c9393745c62fe27b5ced8;hp=939ddf8fad842ac947b427f28a09ee3810f8de42;hpb=e85002753464f0e4216a82538988d3ea81dac158;p=controller.git diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerSupport.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerSupport.java index 939ddf8fad..2e26e6ee36 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerSupport.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerSupport.java @@ -7,91 +7,113 @@ */ package org.opendaylight.controller.cluster.datastore; -import java.util.ArrayList; -import java.util.List; import akka.actor.ActorRef; import akka.actor.ActorSelection; +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.RegisterChangeListener; import org.opendaylight.controller.cluster.datastore.messages.RegisterChangeListenerReply; +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.store.impl.DataChangeListenerRegistration; import org.opendaylight.yangtools.concepts.ListenerRegistration; 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 org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate; + +final class DataChangeListenerSupport extends AbstractDataListenerSupport< + AsyncDataChangeListener>, RegisterChangeListener, + DelayedDataChangeListenerRegistration, DataChangeListenerRegistration< + AsyncDataChangeListener>>> { -final class DataChangeListenerSupport extends LeaderLocalDelegateFactory>>> { - private static final Logger LOG = LoggerFactory.getLogger(DataChangeListenerSupport.class); - private final List delayedListenerRegistrations = new ArrayList<>(); - private final List dataChangeListeners = new ArrayList<>(); + private final Set listenerActors = Sets.newConcurrentHashSet(); DataChangeListenerSupport(final Shard shard) { super(shard); } + Collection getListenerActors() { + return new ArrayList<>(listenerActors); + } + @Override - void onLeadershipChange(final boolean isLeader) { - for (ActorSelection dataChangeListener : dataChangeListeners) { - dataChangeListener.tell(new EnableNotification(isLeader), getSelf()); - } + DataChangeListenerRegistration>> + createDelegate(final RegisterChangeListener message) { + final ActorSelection dataChangeListenerPath = selectActor(message.getDataChangeListenerPath()); - if (isLeader) { - for (DelayedListenerRegistration reg: delayedListenerRegistrations) { - if(!reg.isClosed()) { - reg.setDelegate(createDelegate(reg.getRegisterChangeListener())); - } - } + // 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), getSelf()); - delayedListenerRegistrations.clear(); + // 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 + if (!message.isRegisterOnAllInstances()) { + addListenerActor(dataChangeListenerPath); } - } - @Override - void onMessage(final RegisterChangeListener message, final boolean isLeader) { + AsyncDataChangeListener> listener = + new DataChangeListenerProxy(dataChangeListenerPath); - LOG.debug("{}: registerDataChangeListener for {}, leader: {}", persistenceId(), message.getPath(), isLeader); + log().debug("{}: Registering for path {}", persistenceId(), message.getPath()); - ListenerRegistration>> registration; - if (isLeader) { - registration = createDelegate(message); - } else { - LOG.debug("{}: Shard is not the leader - delaying registration", persistenceId()); + Entry>>, + Optional> regEntry = getShard().getDataStore().registerChangeListener( + message.getPath(), listener, message.getScope()); - DelayedListenerRegistration delayedReg = new DelayedListenerRegistration(message); - delayedListenerRegistrations.add(delayedReg); - registration = delayedReg; - } + getShard().getDataStore().notifyOfInitialData(regEntry.getKey(), regEntry.getValue()); - ActorRef listenerRegistration = createActor(DataChangeListenerRegistration.props(registration)); + listenerActors.add(dataChangeListenerPath); + final DataChangeListenerRegistration>> + delegate = regEntry.getKey(); + return new DataChangeListenerRegistration>>() { + @Override + public void close() { + listenerActors.remove(dataChangeListenerPath); + delegate.close(); + } - LOG.debug("{}: registerDataChangeListener sending reply, listenerRegistrationPath = {} ", - persistenceId(), listenerRegistration.path()); + @Override + public AsyncDataChangeListener> getInstance() { + return delegate.getInstance(); + } - tellSender(new RegisterChangeListenerReply(listenerRegistration)); + @Override + public YangInstanceIdentifier getPath() { + return delegate.getPath(); + } + + @Override + public DataChangeScope getScope() { + return delegate.getScope(); + } + }; } @Override - ListenerRegistration>> createDelegate( - final RegisterChangeListener message) { - ActorSelection dataChangeListenerPath = selectActor(message.getDataChangeListenerPath()); - - // 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), 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 - dataChangeListeners.add(dataChangeListenerPath); + protected DelayedDataChangeListenerRegistration newDelayedListenerRegistration(RegisterChangeListener message) { + return new DelayedDataChangeListenerRegistration(message); + } - AsyncDataChangeListener> listener = - new DataChangeListenerProxy(dataChangeListenerPath); + @Override + protected ActorRef newRegistrationActor( + ListenerRegistration>> registration) { + return createActor(DataChangeListenerRegistrationActor.props(registration)); + } - LOG.debug("{}: Registering for path {}", persistenceId(), message.getPath()); + @Override + protected Object newRegistrationReplyMessage(ActorRef registrationActor) { + return new RegisterChangeListenerReply(registrationActor); + } - return getShard().getDataStore().registerChangeListener(message.getPath(), listener, - message.getScope()); + @Override + protected String logName() { + return "registerDataChangeListener"; } }