* 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 static java.util.Objects.requireNonNull;
+
import akka.actor.ActorRef;
import akka.actor.PoisonPill;
import akka.actor.Status;
import akka.util.Timeout;
-import com.google.common.base.Preconditions;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import javax.annotation.concurrent.NotThreadSafe;
+import java.util.concurrent.Executor;
import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
-import org.opendaylight.controller.cluster.datastore.DataTreeCohortActor.CanCommit;
-import org.opendaylight.controller.md.sal.dom.spi.AbstractRegistrationTree;
-import org.opendaylight.controller.md.sal.dom.spi.RegistrationTreeNode;
-import org.opendaylight.controller.md.sal.dom.spi.RegistrationTreeSnapshot;
import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
import org.opendaylight.mdsal.dom.api.DOMDataTreeCandidate;
import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
+import org.opendaylight.mdsal.dom.spi.AbstractRegistrationTree;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidate;
+import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidateNode;
+import org.opendaylight.yangtools.yang.data.tree.api.ModificationType;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Registry of user commit cohorts, which is responsible for handling registration and calculation
- * of affected cohorts based on {@link DataTreeCandidate}.
- *
+ * of affected cohorts based on {@link DataTreeCandidate}. This class is NOT thread-safe.
*/
-@NotThreadSafe
class DataTreeCohortActorRegistry extends AbstractRegistrationTree<ActorRef> {
private static final Logger LOG = LoggerFactory.getLogger(DataTreeCohortActorRegistry.class);
- private final Map<ActorRef, RegistrationTreeNode<ActorRef>> cohortToNode = new HashMap<>();
+ private final Map<ActorRef, Node<ActorRef>> cohortToNode = new HashMap<>();
+ Collection<ActorRef> getCohortActors() {
+ return new ArrayList<>(cohortToNode.keySet());
+ }
+ @SuppressWarnings("checkstyle:IllegalCatch")
void registerCohort(final ActorRef sender, final RegisterCohort cohort) {
takeLock();
try {
final ActorRef cohortRef = cohort.getCohort();
- final RegistrationTreeNode<ActorRef> node =
- findNodeFor(cohort.getPath().getRootIdentifier().getPathArguments());
+ final Node<ActorRef> node = findNodeFor(cohort.getPath().path().getPathArguments());
addRegistration(node, cohort.getCohort());
cohortToNode.put(cohortRef, node);
} catch (final Exception e) {
void removeCommitCohort(final ActorRef sender, final RemoveCohort message) {
final ActorRef cohort = message.getCohort();
- final RegistrationTreeNode<ActorRef> node = cohortToNode.get(cohort);
+ final Node<ActorRef> node = cohortToNode.get(cohort);
if (node != null) {
removeRegistration(node, cohort);
cohortToNode.remove(cohort);
cohort.tell(PoisonPill.getInstance(), cohort);
}
- Collection<DataTreeCohortActor.CanCommit> createCanCommitMessages(final TransactionIdentifier txId,
- final DataTreeCandidate candidate, final SchemaContext schema) {
- try (RegistrationTreeSnapshot<ActorRef> cohorts = takeSnapshot()) {
+ List<DataTreeCohortActor.CanCommit> createCanCommitMessages(final TransactionIdentifier txId,
+ final DataTreeCandidate candidate, final EffectiveModelContext schema) {
+ try (var cohorts = takeSnapshot()) {
return new CanCommitMessageBuilder(txId, candidate, schema).perform(cohorts.getRootNode());
}
}
}
}
- static abstract class CohortRegistryCommand {
-
+ abstract static class CohortRegistryCommand {
private final ActorRef cohort;
CohortRegistryCommand(final ActorRef cohort) {
- this.cohort = Preconditions.checkNotNull(cohort);
+ this.cohort = requireNonNull(cohort);
}
ActorRef getCohort() {
}
static class RegisterCohort extends CohortRegistryCommand {
-
private final DOMDataTreeIdentifier path;
RegisterCohort(final DOMDataTreeIdentifier path, final ActorRef cohort) {
super(cohort);
this.path = path;
-
}
public DOMDataTreeIdentifier getPath() {
return path;
}
-
}
static class RemoveCohort extends CohortRegistryCommand {
-
RemoveCohort(final ActorRef cohort) {
super(cohort);
}
-
}
private static class CanCommitMessageBuilder {
-
+ private final Multimap<ActorRef, DOMDataTreeCandidate> actorToCandidates = ArrayListMultimap.create();
private final TransactionIdentifier txId;
private final DataTreeCandidate candidate;
- private final SchemaContext schema;
- private final Collection<DataTreeCohortActor.CanCommit> messages =
- new ArrayList<>();
+ private final EffectiveModelContext schema;
- CanCommitMessageBuilder(final TransactionIdentifier txId, final DataTreeCandidate candidate, final SchemaContext schema) {
- this.txId = Preconditions.checkNotNull(txId);
- this.candidate = Preconditions.checkNotNull(candidate);
+ CanCommitMessageBuilder(final TransactionIdentifier txId, final DataTreeCandidate candidate,
+ final EffectiveModelContext schema) {
+ this.txId = requireNonNull(txId);
+ this.candidate = requireNonNull(candidate);
this.schema = schema;
}
private void lookupAndCreateCanCommits(final List<PathArgument> args, final int offset,
- final RegistrationTreeNode<ActorRef> node) {
+ final Node<ActorRef> node) {
if (args.size() != offset) {
final PathArgument arg = args.get(offset);
- final RegistrationTreeNode<ActorRef> exactChild = node.getExactChild(arg);
+ final var exactChild = node.getExactChild(arg);
if (exactChild != null) {
lookupAndCreateCanCommits(args, offset + 1, exactChild);
}
- for (final RegistrationTreeNode<ActorRef> c : node.getInexactChildren(arg)) {
- lookupAndCreateCanCommits(args, offset + 1, c);
+ for (var inexact : node.getInexactChildren(arg)) {
+ lookupAndCreateCanCommits(args, offset + 1, inexact);
}
} else {
lookupAndCreateCanCommits(candidate.getRootPath(), node, candidate.getRootNode());
}
}
- private void lookupAndCreateCanCommits(final YangInstanceIdentifier path, final RegistrationTreeNode<ActorRef> regNode,
+ private void lookupAndCreateCanCommits(final YangInstanceIdentifier path, final Node<ActorRef> regNode,
final DataTreeCandidateNode candNode) {
- if (candNode.getModificationType() == ModificationType.UNMODIFIED) {
+ if (candNode.modificationType() == ModificationType.UNMODIFIED) {
LOG.debug("Skipping unmodified candidate {}", path);
return;
}
- final Collection<ActorRef> regs = regNode.getRegistrations();
+ final var regs = regNode.getRegistrations();
if (!regs.isEmpty()) {
createCanCommits(regs, path, candNode);
}
- for (final DataTreeCandidateNode candChild : candNode.getChildNodes()) {
- if (candChild.getModificationType() != ModificationType.UNMODIFIED) {
- final RegistrationTreeNode<ActorRef> regChild =
- regNode.getExactChild(candChild.getIdentifier());
+ for (var candChild : candNode.childNodes()) {
+ if (candChild.modificationType() != ModificationType.UNMODIFIED) {
+ final var regChild = regNode.getExactChild(candChild.name());
if (regChild != null) {
- lookupAndCreateCanCommits(path.node(candChild.getIdentifier()), regChild, candChild);
+ lookupAndCreateCanCommits(path.node(candChild.name()), regChild, candChild);
}
- for (final RegistrationTreeNode<ActorRef> rc : regNode
- .getInexactChildren(candChild.getIdentifier())) {
- lookupAndCreateCanCommits(path.node(candChild.getIdentifier()), rc, candChild);
+ for (var rc : regNode.getInexactChildren(candChild.name())) {
+ lookupAndCreateCanCommits(path.node(candChild.name()), rc, candChild);
}
}
}
private void createCanCommits(final Collection<ActorRef> regs, final YangInstanceIdentifier path,
final DataTreeCandidateNode node) {
- final DOMDataTreeCandidate candidate = DOMDataTreeCandidateTO.create(treeIdentifier(path), node);
+ final DOMDataTreeCandidate domCandidate = DOMDataTreeCandidateTO.create(treeIdentifier(path), node);
for (final ActorRef reg : regs) {
- final CanCommit message = new DataTreeCohortActor.CanCommit(txId, candidate, schema, reg);
- messages.add(message);
+ actorToCandidates.put(reg, domCandidate);
}
}
private static DOMDataTreeIdentifier treeIdentifier(final YangInstanceIdentifier path) {
- return new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, path);
+ return DOMDataTreeIdentifier.of(LogicalDatastoreType.CONFIGURATION, path);
}
- private Collection<DataTreeCohortActor.CanCommit> perform(final RegistrationTreeNode<ActorRef> rootNode) {
- final List<PathArgument> toLookup = candidate.getRootPath().getPathArguments();
+ List<DataTreeCohortActor.CanCommit> perform(final Node<ActorRef> rootNode) {
+ final var toLookup = candidate.getRootPath().getPathArguments();
lookupAndCreateCanCommits(toLookup, 0, rootNode);
+
+ final Map<ActorRef, Collection<DOMDataTreeCandidate>> mapView = actorToCandidates.asMap();
+ final List<DataTreeCohortActor.CanCommit> messages = new ArrayList<>(mapView.size());
+ for (Map.Entry<ActorRef, Collection<DOMDataTreeCandidate>> entry: mapView.entrySet()) {
+ messages.add(new DataTreeCohortActor.CanCommit(txId, entry.getValue(), schema, entry.getKey()));
+ }
+
return messages;
}
}
- CompositeDataTreeCohort createCohort(final SchemaContext schemaContext, final TransactionIdentifier txId,
- final Timeout commitStepTimeout) {
- return new CompositeDataTreeCohort(this, txId, schemaContext, commitStepTimeout);
+ CompositeDataTreeCohort createCohort(final EffectiveModelContext schemaContext, final TransactionIdentifier txId,
+ final Executor callbackExecutor, final Timeout commitStepTimeout) {
+ return new CompositeDataTreeCohort(this, txId, schemaContext, callbackExecutor, commitStepTimeout);
}
}