Remove sal-distrubited-eos 51/96751/1
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 30 Jun 2021 20:16:56 +0000 (22:16 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Wed, 30 Jun 2021 20:20:33 +0000 (22:20 +0200)
There are no more packaging references to datastore-based entity
ownership. Remove the implementation.

JIRA: CONTROLLER-1982
Change-Id: Ia6a96a1853e0f173d7af559c76a06e9dfadc540e
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
46 files changed:
artifacts/pom.xml
opendaylight/md-sal/pom.xml
opendaylight/md-sal/sal-distributed-eos/pom.xml [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/AbstractEntityOwnerChangeListener.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/CandidateListChangeListener.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/DistributedEntityOwnershipCandidateRegistration.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/DistributedEntityOwnershipListenerRegistration.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/DistributedEntityOwnershipService.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/EntityOwnerChangeListener.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/EntityOwnersModel.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/EntityOwnershipChangePublisher.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/EntityOwnershipListenerActor.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/EntityOwnershipListenerSupport.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/EntityOwnershipShard.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/EntityOwnershipShardCommitCoordinator.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/EntityOwnershipStatistics.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/OSGiDistributedEntityOwnershipService.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/messages/CandidateAdded.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/messages/CandidateRemoved.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/messages/RegisterCandidateLocal.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/messages/RegisterListenerLocal.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/messages/RemoveAllCandidates.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/messages/SelectOwner.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/messages/UnregisterCandidateLocal.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/messages/UnregisterListenerLocal.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/selectionstrategy/AbstractEntityOwnerSelectionStrategy.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/selectionstrategy/EntityOwnerSelectionStrategy.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/selectionstrategy/EntityOwnerSelectionStrategyConfig.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/selectionstrategy/EntityOwnerSelectionStrategyConfigReader.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/selectionstrategy/FirstCandidateSelectionStrategy.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/selectionstrategy/LeastLoadedCandidateSelectionStrategy.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/main/yang/entity-owners.yang [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/AbstractClusterRefEntityOwnershipTest.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/AbstractEntityOwnershipTest.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/CandidateListChangeListenerTest.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/DistributedEntityOwnershipIntegrationTest.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/DistributedEntityOwnershipServiceTest.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/EOSTestUtils.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/EntityOwnerChangeListenerTest.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/EntityOwnershipListenerActorTest.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/EntityOwnershipListenerSupportTest.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/EntityOwnershipShardTest.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/EntityOwnershipStatisticsTest.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/selectionstrategy/EntityOwnerSelectionStrategyConfigReaderTest.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/selectionstrategy/LastCandidateSelectionStrategy.java [deleted file]
opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/selectionstrategy/LeastLoadedCandidateSelectionStrategyTest.java [deleted file]

index 6e83e398fe0ae14ddb335bcbec35ea1bd5810ef2..c02b567ecd9091205e50a9ce19fda7c4e9e3759e 100644 (file)
                 <artifactId>sal-distributed-datastore</artifactId>
                 <version>${project.version}</version>
             </dependency>
                 <artifactId>sal-distributed-datastore</artifactId>
                 <version>${project.version}</version>
             </dependency>
-            <dependency>
-                <groupId>${project.groupId}</groupId>
-                <artifactId>sal-distributed-eos</artifactId>
-                <version>${project.version}</version>
-            </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>
                 <artifactId>sal-remoterpc-connector</artifactId>
             <dependency>
                 <groupId>${project.groupId}</groupId>
                 <artifactId>sal-remoterpc-connector</artifactId>
index 6b63828472b31bc0f33300bc73320931f31f697d..b430b527ef51b4516812db6fb81b58713465f19c 100644 (file)
@@ -46,7 +46,8 @@
     <module>sal-dummy-distributed-datastore</module>
     <module>sal-cluster-admin-api</module>
     <module>sal-cluster-admin-impl</module>
     <module>sal-dummy-distributed-datastore</module>
     <module>sal-cluster-admin-api</module>
     <module>sal-cluster-admin-impl</module>
-    <module>sal-distributed-eos</module>
+
+    <!-- Entity Ownership Service on top of Akka Distributed Data/Singleton -->
     <module>eos-dom-akka</module>
 
     <!-- Yang Test Models for MD-SAL -->
     <module>eos-dom-akka</module>
 
     <!-- Yang Test Models for MD-SAL -->
diff --git a/opendaylight/md-sal/sal-distributed-eos/pom.xml b/opendaylight/md-sal/sal-distributed-eos/pom.xml
deleted file mode 100644 (file)
index ac855a6..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.opendaylight.controller</groupId>
-    <artifactId>mdsal-parent</artifactId>
-    <version>4.0.0-SNAPSHOT</version>
-    <relativePath>../parent</relativePath>
-  </parent>
-
-  <artifactId>sal-distributed-eos</artifactId>
-  <packaging>bundle</packaging>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.opendaylight.mdsal</groupId>
-      <artifactId>mdsal-eos-dom-api</artifactId>
-    </dependency>
-
-    <dependency>
-      <groupId>org.osgi</groupId>
-      <artifactId>osgi.cmpn</artifactId>
-    </dependency>
-
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal-distributed-datastore</artifactId>
-    </dependency>
-
-    <dependency>
-      <groupId>commons-lang</groupId>
-      <artifactId>commons-lang</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>com.typesafe.akka</groupId>
-      <artifactId>akka-testkit_2.13</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal-akka-raft-example</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal-akka-raft</artifactId>
-      <type>test-jar</type>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal-distributed-datastore</artifactId>
-      <version>${project.version}</version>
-      <type>test-jar</type>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-simple</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.yangtools</groupId>
-      <artifactId>yang-test-util</artifactId>
-    </dependency>
-  </dependencies>
-
-  <scm>
-    <connection>scm:git:http://git.opendaylight.org/gerrit/controller.git</connection>
-    <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
-    <tag>HEAD</tag>
-    <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Architecture:Clustering</url>
-  </scm>
-</project>
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/AbstractEntityOwnerChangeListener.java b/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/AbstractEntityOwnerChangeListener.java
deleted file mode 100644 (file)
index eb81e99..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco 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.entityownership;
-
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.ENTITY_OWNERS_PATH;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.ENTITY_OWNER_QNAME;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.ENTITY_QNAME;
-
-import java.util.Optional;
-import org.opendaylight.controller.cluster.datastore.ShardDataTree;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.clustering.entity.owners.rev150804.entity.owners.EntityType;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-
-public abstract class AbstractEntityOwnerChangeListener implements DOMDataTreeChangeListener {
-    private static final YangInstanceIdentifier EOS_PATH = YangInstanceIdentifier.builder(ENTITY_OWNERS_PATH)
-            .node(EntityType.QNAME).node(EntityType.QNAME).node(ENTITY_QNAME).node(ENTITY_QNAME)
-            .node(ENTITY_OWNER_QNAME).build();
-
-    void init(final ShardDataTree shardDataTree) {
-        shardDataTree.registerTreeChangeListener(EOS_PATH, this, Optional.empty(), noop -> { /* NOOP */ });
-    }
-
-    protected static String extractOwner(final LeafNode<?> ownerLeaf) {
-        return ownerLeaf.body().toString();
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/CandidateListChangeListener.java b/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/CandidateListChangeListener.java
deleted file mode 100644 (file)
index d8df830..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco 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.entityownership;
-
-import static java.util.Objects.requireNonNull;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.CANDIDATE_NAME_QNAME;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.ENTITY_ID_QNAME;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.ENTITY_OWNERS_PATH;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.ENTITY_QNAME;
-
-import akka.actor.ActorRef;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import org.opendaylight.controller.cluster.datastore.ShardDataTree;
-import org.opendaylight.controller.cluster.entityownership.messages.CandidateAdded;
-import org.opendaylight.controller.cluster.entityownership.messages.CandidateRemoved;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.clustering.entity.owners.rev150804.entity.owners.EntityType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.clustering.entity.owners.rev150804.entity.owners.entity.type.entity.Candidate;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-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.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Listens for candidate entries added/removed and notifies the EntityOwnershipShard appropriately.
- *
- * @author Moiz Raja
- * @author Thomas Pantelis
- */
-class CandidateListChangeListener implements DOMDataTreeChangeListener {
-    private static final Logger LOG = LoggerFactory.getLogger(CandidateListChangeListener.class);
-
-    private final String logId;
-    private final ActorRef shard;
-    private final Map<YangInstanceIdentifier, Collection<String>> currentCandidates = new HashMap<>();
-
-    CandidateListChangeListener(final ActorRef shard, final String logId) {
-        this.shard = requireNonNull(shard, "shard should not be null");
-        this.logId = logId;
-    }
-
-    void init(final ShardDataTree shardDataTree) {
-        shardDataTree.registerTreeChangeListener(YangInstanceIdentifier.builder(ENTITY_OWNERS_PATH)
-            .node(EntityType.QNAME).node(EntityType.QNAME).node(ENTITY_QNAME).node(ENTITY_QNAME)
-                .node(Candidate.QNAME).node(Candidate.QNAME).build(), this, Optional.empty(), noop -> { /* NOOP */ });
-    }
-
-    @Override
-    public void onInitialData() {
-        // No-op
-    }
-
-    @Override
-    public void onDataTreeChanged(final Collection<DataTreeCandidate> changes) {
-        for (DataTreeCandidate change: changes) {
-            DataTreeCandidateNode changeRoot = change.getRootNode();
-            ModificationType type = changeRoot.getModificationType();
-
-            LOG.debug("{}: Candidate node changed: {}, {}", logId, type, change.getRootPath());
-
-            NodeIdentifierWithPredicates candidateKey =
-                    (NodeIdentifierWithPredicates) change.getRootPath().getLastPathArgument();
-            String candidate = candidateKey.getValue(CANDIDATE_NAME_QNAME).toString();
-
-            YangInstanceIdentifier entityId = extractEntityPath(change.getRootPath());
-
-            if (type == ModificationType.WRITE || type == ModificationType.APPEARED) {
-                LOG.debug("{}: Candidate {} was added for entity {}", logId, candidate, entityId);
-
-                Collection<String> newCandidates = addToCurrentCandidates(entityId, candidate);
-                shard.tell(new CandidateAdded(entityId, candidate, new ArrayList<>(newCandidates)), shard);
-            } else if (type == ModificationType.DELETE || type == ModificationType.DISAPPEARED) {
-                LOG.debug("{}: Candidate {} was removed for entity {}", logId, candidate, entityId);
-
-                Collection<String> newCandidates = removeFromCurrentCandidates(entityId, candidate);
-                shard.tell(new CandidateRemoved(entityId, candidate, new ArrayList<>(newCandidates)), shard);
-            }
-        }
-    }
-
-    private Collection<String> addToCurrentCandidates(final YangInstanceIdentifier entityId,
-            final String newCandidate) {
-        Collection<String> candidates = currentCandidates.computeIfAbsent(entityId, k -> new LinkedHashSet<>());
-        candidates.add(newCandidate);
-        return candidates;
-    }
-
-    private Collection<String> removeFromCurrentCandidates(final YangInstanceIdentifier entityId,
-            final String candidateToRemove) {
-        Collection<String> candidates = currentCandidates.get(entityId);
-        if (candidates != null) {
-            candidates.remove(candidateToRemove);
-            return candidates;
-        }
-
-        // Shouldn't happen
-        return Collections.emptyList();
-    }
-
-    private static YangInstanceIdentifier extractEntityPath(final YangInstanceIdentifier candidatePath) {
-        List<PathArgument> newPathArgs = new ArrayList<>();
-        for (PathArgument pathArg: candidatePath.getPathArguments()) {
-            newPathArgs.add(pathArg);
-            if (pathArg instanceof NodeIdentifierWithPredicates
-                    && ENTITY_ID_QNAME.equals(((NodeIdentifierWithPredicates) pathArg).keySet().iterator().next())) {
-                break;
-            }
-        }
-
-        return YangInstanceIdentifier.create(newPathArgs);
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/DistributedEntityOwnershipCandidateRegistration.java b/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/DistributedEntityOwnershipCandidateRegistration.java
deleted file mode 100644 (file)
index 4888f6e..0000000
+++ /dev/null
@@ -1,33 +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.entityownership;
-
-import org.opendaylight.mdsal.eos.dom.api.DOMEntity;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipCandidateRegistration;
-import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
-
-/**
- * Implementation of EntityOwnershipCandidateRegistration.
- *
- * @author Thomas Pantelis
- */
-class DistributedEntityOwnershipCandidateRegistration extends AbstractObjectRegistration<DOMEntity>
-        implements DOMEntityOwnershipCandidateRegistration {
-    private final DistributedEntityOwnershipService service;
-
-    DistributedEntityOwnershipCandidateRegistration(final DOMEntity entity,
-            final DistributedEntityOwnershipService service) {
-        super(entity);
-        this.service = service;
-    }
-
-    @Override
-    protected void removeRegistration() {
-        service.unregisterCandidate(getInstance());
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/DistributedEntityOwnershipListenerRegistration.java b/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/DistributedEntityOwnershipListenerRegistration.java
deleted file mode 100644 (file)
index bb4e31c..0000000
+++ /dev/null
@@ -1,48 +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.entityownership;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.base.MoreObjects.ToStringHelper;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipListener;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipListenerRegistration;
-import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
-
-/**
- * Implementation of EntityOwnershipListenerRegistration.
- *
- * @author Thomas Pantelis
- */
-class DistributedEntityOwnershipListenerRegistration extends AbstractObjectRegistration<DOMEntityOwnershipListener>
-        implements DOMEntityOwnershipListenerRegistration {
-    private final DistributedEntityOwnershipService service;
-    private final String entityType;
-
-    DistributedEntityOwnershipListenerRegistration(final DOMEntityOwnershipListener listener, final String entityType,
-            final DistributedEntityOwnershipService service) {
-        super(listener);
-        this.entityType = requireNonNull(entityType, "entityType cannot be null");
-        this.service = requireNonNull(service, "DOMEntityOwnershipListener cannot be null");
-    }
-
-    @Override
-    protected void removeRegistration() {
-        service.unregisterListener(getEntityType(), getInstance());
-    }
-
-    @Override
-    public String getEntityType() {
-        return entityType;
-    }
-
-    @Override
-    protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
-        return toStringHelper.add("entityType", entityType);
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/DistributedEntityOwnershipService.java b/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/DistributedEntityOwnershipService.java
deleted file mode 100644 (file)
index 5a519d4..0000000
+++ /dev/null
@@ -1,264 +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.entityownership;
-
-import static java.util.Objects.requireNonNull;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.CANDIDATE_NODE_ID;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.ENTITY_OWNER_NODE_ID;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.entityPath;
-
-import akka.actor.ActorRef;
-import akka.dispatch.OnComplete;
-import akka.pattern.Patterns;
-import akka.util.Timeout;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Strings;
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-import java.util.Collection;
-import java.util.Optional;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import org.opendaylight.controller.cluster.access.concepts.MemberName;
-import org.opendaylight.controller.cluster.datastore.config.Configuration;
-import org.opendaylight.controller.cluster.datastore.config.ModuleShardConfiguration;
-import org.opendaylight.controller.cluster.datastore.messages.CreateShard;
-import org.opendaylight.controller.cluster.datastore.messages.GetShardDataTree;
-import org.opendaylight.controller.cluster.datastore.shardstrategy.ModuleShardStrategy;
-import org.opendaylight.controller.cluster.datastore.utils.ActorUtils;
-import org.opendaylight.controller.cluster.entityownership.messages.RegisterCandidateLocal;
-import org.opendaylight.controller.cluster.entityownership.messages.RegisterListenerLocal;
-import org.opendaylight.controller.cluster.entityownership.messages.UnregisterCandidateLocal;
-import org.opendaylight.controller.cluster.entityownership.messages.UnregisterListenerLocal;
-import org.opendaylight.controller.cluster.entityownership.selectionstrategy.EntityOwnerSelectionStrategyConfig;
-import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException;
-import org.opendaylight.mdsal.eos.common.api.EntityOwnershipState;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntity;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipCandidateRegistration;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipListener;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipListenerRegistration;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.clustering.entity.owners.rev150804.EntityOwners;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import scala.concurrent.Await;
-import scala.concurrent.Future;
-import scala.concurrent.duration.Duration;
-
-/**
- * The distributed implementation of the EntityOwnershipService.
- *
- * @author Thomas Pantelis
- */
-public class DistributedEntityOwnershipService implements DOMEntityOwnershipService, AutoCloseable {
-    @VisibleForTesting
-    static final String ENTITY_OWNERSHIP_SHARD_NAME = "entity-ownership";
-
-    private static final Logger LOG = LoggerFactory.getLogger(DistributedEntityOwnershipService.class);
-    private static final Timeout MESSAGE_TIMEOUT = new Timeout(1, TimeUnit.MINUTES);
-
-    private final ConcurrentMap<DOMEntity, DOMEntity> registeredEntities = new ConcurrentHashMap<>();
-    private final ActorUtils context;
-
-    private volatile ActorRef localEntityOwnershipShard;
-    private volatile DataTree localEntityOwnershipShardDataTree;
-
-    DistributedEntityOwnershipService(final ActorUtils context) {
-        this.context = requireNonNull(context);
-    }
-
-    public static DistributedEntityOwnershipService start(final ActorUtils context,
-            final EntityOwnerSelectionStrategyConfig strategyConfig) {
-        ActorRef shardManagerActor = context.getShardManager();
-
-        Configuration configuration = context.getConfiguration();
-        Collection<MemberName> entityOwnersMemberNames = configuration.getUniqueMemberNamesForAllShards();
-        CreateShard createShard = new CreateShard(new ModuleShardConfiguration(EntityOwners.QNAME.getNamespace(),
-                "entity-owners", ENTITY_OWNERSHIP_SHARD_NAME, ModuleShardStrategy.NAME, entityOwnersMemberNames),
-                        newShardBuilder(context, strategyConfig), null);
-
-        Future<Object> createFuture = context.executeOperationAsync(shardManagerActor, createShard, MESSAGE_TIMEOUT);
-        createFuture.onComplete(new OnComplete<>() {
-            @Override
-            public void onComplete(final Throwable failure, final Object response) {
-                if (failure != null) {
-                    LOG.error("Failed to create {} shard", ENTITY_OWNERSHIP_SHARD_NAME, failure);
-                } else {
-                    LOG.info("Successfully created {} shard", ENTITY_OWNERSHIP_SHARD_NAME);
-                }
-            }
-        }, context.getClientDispatcher());
-
-        return new DistributedEntityOwnershipService(context);
-    }
-
-    private void executeEntityOwnershipShardOperation(final ActorRef shardActor, final Object message) {
-        Future<Object> future = context.executeOperationAsync(shardActor, message, MESSAGE_TIMEOUT);
-        future.onComplete(new OnComplete<>() {
-            @Override
-            public void onComplete(final Throwable failure, final Object response) {
-                if (failure != null) {
-                    // FIXME: CONTROLLER-1904: reduce the severity to info once we have a retry mechanism
-                    LOG.error("Error sending message {} to {}", message, shardActor, failure);
-                } else {
-                    LOG.debug("{} message to {} succeeded", message, shardActor);
-                }
-            }
-        }, context.getClientDispatcher());
-    }
-
-    @VisibleForTesting
-    void executeLocalEntityOwnershipShardOperation(final Object message) {
-        if (localEntityOwnershipShard == null) {
-            Future<ActorRef> future = context.findLocalShardAsync(ENTITY_OWNERSHIP_SHARD_NAME);
-            future.onComplete(new OnComplete<ActorRef>() {
-                @Override
-                public void onComplete(final Throwable failure, final ActorRef shardActor) {
-                    if (failure != null) {
-                        // FIXME: CONTROLLER-1904: reduce the severity to info once we have a retry mechanism
-                        LOG.error("Failed to find local {} shard", ENTITY_OWNERSHIP_SHARD_NAME, failure);
-                    } else {
-                        localEntityOwnershipShard = shardActor;
-                        executeEntityOwnershipShardOperation(localEntityOwnershipShard, message);
-                    }
-                }
-            }, context.getClientDispatcher());
-
-        } else {
-            executeEntityOwnershipShardOperation(localEntityOwnershipShard, message);
-        }
-    }
-
-    @Override
-    public DOMEntityOwnershipCandidateRegistration registerCandidate(final DOMEntity entity)
-            throws CandidateAlreadyRegisteredException {
-        requireNonNull(entity, "entity cannot be null");
-
-        if (registeredEntities.putIfAbsent(entity, entity) != null) {
-            throw new CandidateAlreadyRegisteredException(entity);
-        }
-
-        RegisterCandidateLocal registerCandidate = new RegisterCandidateLocal(entity);
-
-        LOG.debug("Registering candidate with message: {}", registerCandidate);
-
-        executeLocalEntityOwnershipShardOperation(registerCandidate);
-        return new DistributedEntityOwnershipCandidateRegistration(entity, this);
-    }
-
-    void unregisterCandidate(final DOMEntity entity) {
-        LOG.debug("Unregistering candidate for {}", entity);
-
-        executeLocalEntityOwnershipShardOperation(new UnregisterCandidateLocal(entity));
-        registeredEntities.remove(entity);
-    }
-
-    @Override
-    public DOMEntityOwnershipListenerRegistration registerListener(final String entityType,
-            final DOMEntityOwnershipListener listener) {
-        RegisterListenerLocal registerListener = new RegisterListenerLocal(listener, entityType);
-
-        LOG.debug("Registering listener with message: {}", registerListener);
-
-        executeLocalEntityOwnershipShardOperation(registerListener);
-        return new DistributedEntityOwnershipListenerRegistration(listener, entityType, this);
-    }
-
-    @Override
-    public Optional<EntityOwnershipState> getOwnershipState(final DOMEntity forEntity) {
-        requireNonNull(forEntity, "forEntity cannot be null");
-
-        DataTree dataTree = getLocalEntityOwnershipShardDataTree();
-        if (dataTree == null) {
-            return Optional.empty();
-        }
-
-        Optional<NormalizedNode> entityNode = dataTree.takeSnapshot().readNode(
-                entityPath(forEntity.getType(), forEntity.getIdentifier()));
-        if (!entityNode.isPresent()) {
-            return Optional.empty();
-        }
-
-        // Check if there are any candidates, if there are none we do not really have ownership state
-        final MapEntryNode entity = (MapEntryNode) entityNode.get();
-        final Optional<DataContainerChild> optionalCandidates = entity.findChildByArg(CANDIDATE_NODE_ID);
-        final boolean hasCandidates = optionalCandidates.isPresent()
-                && ((MapNode) optionalCandidates.get()).body().size() > 0;
-        if (!hasCandidates) {
-            return Optional.empty();
-        }
-
-        MemberName localMemberName = context.getCurrentMemberName();
-        Optional<DataContainerChild> ownerLeaf = entity.findChildByArg(ENTITY_OWNER_NODE_ID);
-        String owner = ownerLeaf.isPresent() ? ownerLeaf.get().body().toString() : null;
-        boolean hasOwner = !Strings.isNullOrEmpty(owner);
-        boolean isOwner = hasOwner && localMemberName.getName().equals(owner);
-
-        return Optional.of(EntityOwnershipState.from(isOwner, hasOwner));
-    }
-
-    @Override
-    public boolean isCandidateRegistered(final DOMEntity entity) {
-        return registeredEntities.get(entity) != null;
-    }
-
-    @VisibleForTesting
-    @SuppressWarnings("checkstyle:IllegalCatch")
-    @SuppressFBWarnings(value = "REC_CATCH_EXCEPTION", justification = "Akka's Await.result() API contract")
-    DataTree getLocalEntityOwnershipShardDataTree() {
-        final DataTree local = localEntityOwnershipShardDataTree;
-        if (local != null) {
-            return local;
-        }
-
-        if (localEntityOwnershipShard == null) {
-            try {
-                localEntityOwnershipShard = Await.result(context.findLocalShardAsync(
-                    ENTITY_OWNERSHIP_SHARD_NAME), Duration.Inf());
-            } catch (TimeoutException | InterruptedException e) {
-                LOG.error("Failed to find local {} shard", ENTITY_OWNERSHIP_SHARD_NAME, e);
-                return null;
-            }
-        }
-
-        try {
-            return localEntityOwnershipShardDataTree = (DataTree) Await.result(Patterns.ask(localEntityOwnershipShard,
-                GetShardDataTree.INSTANCE, MESSAGE_TIMEOUT), Duration.Inf());
-        } catch (TimeoutException | InterruptedException e) {
-            LOG.error("Failed to find local {} shard", ENTITY_OWNERSHIP_SHARD_NAME, e);
-            return null;
-        }
-    }
-
-    void unregisterListener(final String entityType, final DOMEntityOwnershipListener listener) {
-        LOG.debug("Unregistering listener {} for entity type {}", listener, entityType);
-
-        executeLocalEntityOwnershipShardOperation(new UnregisterListenerLocal(listener, entityType));
-    }
-
-    @Override
-    public void close() {
-    }
-
-    private static EntityOwnershipShard.Builder newShardBuilder(final ActorUtils context,
-            final EntityOwnerSelectionStrategyConfig strategyConfig) {
-        return EntityOwnershipShard.newBuilder().localMemberName(context.getCurrentMemberName())
-                .ownerSelectionStrategyConfig(strategyConfig);
-    }
-
-    @VisibleForTesting
-    ActorRef getLocalEntityOwnershipShard() {
-        return localEntityOwnershipShard;
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/EntityOwnerChangeListener.java b/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/EntityOwnerChangeListener.java
deleted file mode 100644 (file)
index 974b5a1..0000000
+++ /dev/null
@@ -1,86 +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.entityownership;
-
-import static com.google.common.base.Verify.verifyNotNull;
-import static java.util.Objects.requireNonNull;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.createEntity;
-
-import com.google.common.base.Strings;
-import java.util.Collection;
-import java.util.Objects;
-import java.util.Optional;
-import org.opendaylight.controller.cluster.access.concepts.MemberName;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntity;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Listens for entity owner changes and notifies the EntityOwnershipListenerSupport appropriately.
- *
- * @author Thomas Pantelis
- */
-class EntityOwnerChangeListener extends AbstractEntityOwnerChangeListener {
-    private static final Logger LOG = LoggerFactory.getLogger(EntityOwnerChangeListener.class);
-
-    private final String localMemberName;
-    private final EntityOwnershipChangePublisher publisher;
-
-    EntityOwnerChangeListener(final MemberName localMemberName, final EntityOwnershipChangePublisher publisher) {
-        this.localMemberName = verifyNotNull(localMemberName.getName());
-        this.publisher = requireNonNull(publisher);
-    }
-
-    @Override
-    public void onInitialData() {
-        // No-op
-    }
-
-    @Override
-    public void onDataTreeChanged(final Collection<DataTreeCandidate> changes) {
-        for (DataTreeCandidate change: changes) {
-            DataTreeCandidateNode changeRoot = change.getRootNode();
-            LeafNode<?> ownerLeaf = (LeafNode<?>) changeRoot.getDataAfter().get();
-
-            LOG.debug("{}: Entity node changed: {}, {}", logId(), changeRoot.getModificationType(),
-                    change.getRootPath());
-
-            String newOwner = extractOwner(ownerLeaf);
-
-            String origOwner = null;
-            Optional<NormalizedNode> dataBefore = changeRoot.getDataBefore();
-            if (dataBefore.isPresent()) {
-                origOwner = extractOwner((LeafNode<?>) changeRoot.getDataBefore().get());
-            }
-
-            LOG.debug("{}: New owner: {}, Original owner: {}", logId(), newOwner, origOwner);
-
-            if (!Objects.equals(origOwner, newOwner)) {
-                boolean isOwner = localMemberName.equals(newOwner);
-                boolean wasOwner = localMemberName.equals(origOwner);
-                boolean hasOwner = !Strings.isNullOrEmpty(newOwner);
-
-                DOMEntity entity = createEntity(change.getRootPath());
-
-                LOG.debug(
-                    "{}: Calling notifyEntityOwnershipListeners: entity: {}, wasOwner: {}, isOwner: {}, hasOwner: {}",
-                    logId(), entity, wasOwner, isOwner, hasOwner);
-
-                publisher.notifyEntityOwnershipListeners(entity, wasOwner, isOwner, hasOwner);
-            }
-        }
-    }
-
-    private String logId() {
-        return publisher.getLogId();
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/EntityOwnersModel.java b/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/EntityOwnersModel.java
deleted file mode 100644 (file)
index 14da8ae..0000000
+++ /dev/null
@@ -1,147 +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.entityownership;
-
-import java.util.Map.Entry;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntity;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.clustering.entity.owners.rev150804.EntityOwners;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.clustering.entity.owners.rev150804.entity.owners.EntityType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.clustering.entity.owners.rev150804.entity.owners.entity.type.Entity;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.clustering.entity.owners.rev150804.entity.owners.entity.type.entity.Candidate;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUserMapNodeBuilder;
-
-/**
- * Utility methods for entity-owners yang model.
- *
- * @author Thomas Pantelis
- */
-public final class EntityOwnersModel {
-    static final QName ENTITY_QNAME = Entity.QNAME;
-    static final QName CANDIDATE_NAME_QNAME = QName.create(Candidate.QNAME, "name").intern();
-    static final QName ENTITY_ID_QNAME = QName.create(ENTITY_QNAME, "id").intern();
-    static final QName ENTITY_OWNER_QNAME = QName.create(ENTITY_QNAME, "owner").intern();
-    static final QName ENTITY_TYPE_QNAME = QName.create(EntityType.QNAME, "type").intern();
-
-    static final NodeIdentifier ENTITY_OWNERS_NODE_ID = NodeIdentifier.create(EntityOwners.QNAME);
-    static final NodeIdentifier ENTITY_OWNER_NODE_ID = NodeIdentifier.create(ENTITY_OWNER_QNAME);
-    static final NodeIdentifier ENTITY_NODE_ID = NodeIdentifier.create(ENTITY_QNAME);
-    static final NodeIdentifier ENTITY_ID_NODE_ID = NodeIdentifier.create(ENTITY_ID_QNAME);
-    static final NodeIdentifier ENTITY_TYPE_NODE_ID = NodeIdentifier.create(ENTITY_TYPE_QNAME);
-    static final NodeIdentifier CANDIDATE_NODE_ID = NodeIdentifier.create(Candidate.QNAME);
-    static final NodeIdentifier CANDIDATE_NAME_NODE_ID = NodeIdentifier.create(CANDIDATE_NAME_QNAME);
-    static final YangInstanceIdentifier ENTITY_OWNERS_PATH = YangInstanceIdentifier.create(ENTITY_OWNERS_NODE_ID);
-    static final YangInstanceIdentifier ENTITY_TYPES_PATH = ENTITY_OWNERS_PATH.node(EntityType.QNAME).toOptimized();
-
-    private EntityOwnersModel() {
-    }
-
-    static YangInstanceIdentifier entityPath(final String entityType, final YangInstanceIdentifier entityId) {
-        return YangInstanceIdentifier.builder(ENTITY_OWNERS_PATH).node(EntityType.QNAME)
-                .nodeWithKey(EntityType.QNAME, ENTITY_TYPE_QNAME, entityType).node(ENTITY_QNAME)
-                        .nodeWithKey(ENTITY_QNAME, ENTITY_ID_QNAME, entityId).build();
-
-    }
-
-    static YangInstanceIdentifier candidatePath(final String entityType, final YangInstanceIdentifier entityId,
-            final String candidateName) {
-        return YangInstanceIdentifier.builder(ENTITY_OWNERS_PATH).node(EntityType.QNAME)
-                .nodeWithKey(EntityType.QNAME, ENTITY_TYPE_QNAME, entityType).node(ENTITY_QNAME)
-                        .nodeWithKey(ENTITY_QNAME, ENTITY_ID_QNAME, entityId).node(Candidate.QNAME)
-                                .nodeWithKey(Candidate.QNAME, CANDIDATE_NAME_QNAME, candidateName).build();
-    }
-
-    static YangInstanceIdentifier candidatePath(final YangInstanceIdentifier entityPath, final String candidateName) {
-        return YangInstanceIdentifier.builder(entityPath).node(Candidate.QNAME).nodeWithKey(
-                Candidate.QNAME, CANDIDATE_NAME_QNAME, candidateName).build();
-    }
-
-    static NodeIdentifierWithPredicates candidateNodeKey(final String candidateName) {
-        return NodeIdentifierWithPredicates.of(Candidate.QNAME, CANDIDATE_NAME_QNAME, candidateName);
-    }
-
-    static NormalizedNode entityOwnersWithCandidate(final String entityType,
-            final YangInstanceIdentifier entityId, final String candidateName) {
-        return entityOwnersWithEntityTypeEntry(entityTypeEntryWithEntityEntry(entityType,
-                entityEntryWithCandidateEntry(entityId, candidateName)));
-    }
-
-    static ContainerNode entityOwnersWithEntityTypeEntry(final MapEntryNode entityTypeNode) {
-        return ImmutableContainerNodeBuilder.create().withNodeIdentifier(
-                ENTITY_OWNERS_NODE_ID).addChild(ImmutableNodes.mapNodeBuilder(EntityType.QNAME)
-                        .addChild(entityTypeNode).build()).build();
-    }
-
-    static MapEntryNode entityTypeEntryWithEntityEntry(final String entityType, final MapEntryNode entityNode) {
-        return ImmutableNodes.mapEntryBuilder(EntityType.QNAME,
-                ENTITY_TYPE_QNAME, entityType).addChild(ImmutableNodes.mapNodeBuilder(
-                        ENTITY_QNAME).addChild(entityNode).build()).build();
-    }
-
-    static MapEntryNode entityEntryWithCandidateEntry(final YangInstanceIdentifier entityId,
-            final String candidateName) {
-        return ImmutableNodes.mapEntryBuilder(ENTITY_QNAME, ENTITY_ID_QNAME, entityId).addChild(
-                candidateEntry(candidateName)).build();
-    }
-
-    static MapNode candidateEntry(final String candidateName) {
-        return ImmutableUserMapNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(Candidate.QNAME))
-                .addChild(candidateMapEntry(candidateName)).build();
-    }
-
-    static MapEntryNode candidateMapEntry(final String candidateName) {
-        return ImmutableNodes.mapEntry(Candidate.QNAME, CANDIDATE_NAME_QNAME, candidateName);
-    }
-
-    static MapEntryNode entityEntryWithOwner(final YangInstanceIdentifier entityId, final String owner) {
-        return ImmutableNodes.mapEntryBuilder(ENTITY_QNAME, ENTITY_ID_QNAME, entityId)
-                .addChild(ImmutableNodes.leafNode(ENTITY_OWNER_QNAME, owner != null ? owner : ""))
-                .build();
-    }
-
-    public static String entityTypeFromEntityPath(final YangInstanceIdentifier entityPath) {
-        YangInstanceIdentifier parent = entityPath;
-        while (!parent.isEmpty()) {
-            if (EntityType.QNAME.equals(parent.getLastPathArgument().getNodeType())) {
-                YangInstanceIdentifier.NodeIdentifierWithPredicates entityTypeLastPathArgument =
-                        (YangInstanceIdentifier.NodeIdentifierWithPredicates) parent.getLastPathArgument();
-                return (String) entityTypeLastPathArgument.getValue(ENTITY_TYPE_QNAME);
-            }
-            parent = parent.getParent();
-        }
-        return null;
-    }
-
-    static DOMEntity createEntity(final YangInstanceIdentifier entityPath) {
-        String entityType = null;
-        YangInstanceIdentifier entityId = null;
-        for (PathArgument pathArg: entityPath.getPathArguments()) {
-            if (pathArg instanceof NodeIdentifierWithPredicates) {
-                NodeIdentifierWithPredicates nodeKey = (NodeIdentifierWithPredicates) pathArg;
-                Entry<QName, Object> key = nodeKey.entrySet().iterator().next();
-                if (ENTITY_TYPE_QNAME.equals(key.getKey())) {
-                    entityType = key.getValue().toString();
-                } else if (ENTITY_ID_QNAME.equals(key.getKey())) {
-                    entityId = (YangInstanceIdentifier) key.getValue();
-                }
-            }
-        }
-
-        return new DOMEntity(entityType, entityId);
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/EntityOwnershipChangePublisher.java b/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/EntityOwnershipChangePublisher.java
deleted file mode 100644 (file)
index 18f7ba1..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (c) 2017 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.entityownership;
-
-import org.opendaylight.mdsal.eos.dom.api.DOMEntity;
-
-/**
- * Abstract base for notifying EntityOwnershipListeners.
- *
- * @author Thomas Pantelis
- */
-abstract class EntityOwnershipChangePublisher {
-    abstract void notifyEntityOwnershipListeners(DOMEntity entity, boolean wasOwner, boolean isOwner, boolean hasOwner);
-
-    abstract String getLogId();
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/EntityOwnershipListenerActor.java b/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/EntityOwnershipListenerActor.java
deleted file mode 100644 (file)
index 40e278a..0000000
+++ /dev/null
@@ -1,71 +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.entityownership;
-
-import static java.util.Objects.requireNonNull;
-
-import akka.actor.Props;
-import akka.japi.Creator;
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-import org.opendaylight.controller.cluster.common.actor.AbstractUntypedActor;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipChange;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipListener;
-
-/**
- * An actor which is responsible for notifying an EntityOwnershipListener of changes.
- *
- * @author Thomas Pantelis
- */
-final class EntityOwnershipListenerActor extends AbstractUntypedActor {
-    private final DOMEntityOwnershipListener listener;
-
-    private EntityOwnershipListenerActor(final DOMEntityOwnershipListener listener) {
-        this.listener = listener;
-    }
-
-    @Override
-    protected void handleReceive(final Object message) {
-        if (message instanceof DOMEntityOwnershipChange) {
-            onEntityOwnershipChanged((DOMEntityOwnershipChange)message);
-        } else {
-            unknownMessage(message);
-        }
-    }
-
-    @SuppressWarnings("checkstyle:IllegalCatch")
-    private void onEntityOwnershipChanged(final DOMEntityOwnershipChange change) {
-        LOG.debug("Notifying EntityOwnershipListener {}: {}", listener, change);
-
-        try {
-            listener.ownershipChanged(change);
-        } catch (Exception e) {
-            LOG.error("Error notifying listener {}", listener, e);
-        }
-    }
-
-    static Props props(final DOMEntityOwnershipListener listener) {
-        return Props.create(EntityOwnershipListenerActor.class, new EntityOwnershipListenerCreator(listener));
-    }
-
-    private static final class EntityOwnershipListenerCreator implements Creator<EntityOwnershipListenerActor> {
-        private static final long serialVersionUID = 1L;
-
-        @SuppressFBWarnings(value = "SE_BAD_FIELD", justification = "This field is not Serializable but we don't "
-                + "create remote instances of this actor and thus don't need it to be Serializable.")
-        private final DOMEntityOwnershipListener listener;
-
-        EntityOwnershipListenerCreator(final DOMEntityOwnershipListener listener) {
-            this.listener = requireNonNull(listener);
-        }
-
-        @Override
-        public EntityOwnershipListenerActor create() {
-            return new EntityOwnershipListenerActor(listener);
-        }
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/EntityOwnershipListenerSupport.java b/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/EntityOwnershipListenerSupport.java
deleted file mode 100644 (file)
index c6a710f..0000000
+++ /dev/null
@@ -1,185 +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.entityownership;
-
-import akka.actor.ActorContext;
-import akka.actor.ActorRef;
-import akka.actor.PoisonPill;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Multimap;
-import java.util.Collection;
-import java.util.IdentityHashMap;
-import java.util.Map;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-import java.util.stream.Collectors;
-import org.checkerframework.checker.lock.qual.GuardedBy;
-import org.checkerframework.checker.lock.qual.Holding;
-import org.opendaylight.mdsal.eos.common.api.EntityOwnershipChangeState;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntity;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipChange;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipListener;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Manages EntityOwnershipListener registrations and notifications for the EntityOwnershipShard. This class is
- * thread-safe.
- *
- * @author Thomas Pantelis
- */
-class EntityOwnershipListenerSupport extends EntityOwnershipChangePublisher {
-    private static final Logger LOG = LoggerFactory.getLogger(EntityOwnershipListenerSupport.class);
-
-    private final String logId;
-    private final ActorContext actorContext;
-    private final ReadWriteLock listenerLock = new ReentrantReadWriteLock();
-
-    @GuardedBy("listenerLock")
-    private final Map<DOMEntityOwnershipListener, ListenerActorRefEntry> listenerActorMap = new IdentityHashMap<>();
-
-    @GuardedBy("listenerLock")
-    private final Multimap<String, DOMEntityOwnershipListener> entityTypeListenerMap = HashMultimap.create();
-
-    private volatile boolean inJeopardy = false;
-
-    EntityOwnershipListenerSupport(final ActorContext actorContext, final String logId) {
-        this.actorContext = actorContext;
-        this.logId = logId;
-    }
-
-    @Override
-    String getLogId() {
-        return logId;
-    }
-
-    /**
-     * Set the in-jeopardy flag and indicate its previous state.
-     *
-     * @param inJeopardy new value of the in-jeopardy flag
-     * @return Previous value of the flag.
-     */
-    @SuppressWarnings("checkstyle:hiddenField")
-    boolean setInJeopardy(final boolean inJeopardy) {
-        final boolean wasInJeopardy = this.inJeopardy;
-        this.inJeopardy = inJeopardy;
-        return wasInJeopardy;
-    }
-
-    void addEntityOwnershipListener(final String entityType, final DOMEntityOwnershipListener listener) {
-        LOG.debug("{}: Adding EntityOwnershipListener {} for entity type {}", logId, listener, entityType);
-
-        listenerLock.writeLock().lock();
-        try {
-            if (entityTypeListenerMap.put(entityType, listener)) {
-                ListenerActorRefEntry listenerEntry = listenerActorMap.get(listener);
-                if (listenerEntry == null) {
-                    listenerActorMap.put(listener, new ListenerActorRefEntry(listener));
-                } else {
-                    listenerEntry.referenceCount++;
-                }
-            }
-        } finally {
-            listenerLock.writeLock().unlock();
-        }
-    }
-
-    void removeEntityOwnershipListener(final String entityType, final DOMEntityOwnershipListener listener) {
-        LOG.debug("{}: Removing EntityOwnershipListener {} for entity type {}", logId, listener, entityType);
-
-        listenerLock.writeLock().lock();
-        try {
-            if (entityTypeListenerMap.remove(entityType, listener)) {
-                ListenerActorRefEntry listenerEntry = listenerActorMap.get(listener);
-
-                LOG.debug("{}: Found {}", logId, listenerEntry);
-
-                listenerEntry.referenceCount--;
-                if (listenerEntry.referenceCount <= 0) {
-                    listenerActorMap.remove(listener);
-
-                    if (listenerEntry.actorRef != null) {
-                        LOG.debug("Killing EntityOwnershipListenerActor {}", listenerEntry.actorRef);
-                        listenerEntry.actorRef.tell(PoisonPill.getInstance(), ActorRef.noSender());
-                    }
-                }
-            }
-        } finally {
-            listenerLock.writeLock().unlock();
-        }
-    }
-
-    @Override
-    void notifyEntityOwnershipListeners(final DOMEntity entity, final boolean wasOwner, final boolean isOwner,
-            final boolean hasOwner) {
-        listenerLock.readLock().lock();
-        try {
-            Collection<DOMEntityOwnershipListener> listeners = entityTypeListenerMap.get(entity.getType());
-            if (!listeners.isEmpty()) {
-                notifyListeners(entity, wasOwner, isOwner, hasOwner,
-                        listeners.stream().map(listenerActorMap::get).collect(Collectors.toList()));
-            }
-        } finally {
-            listenerLock.readLock().unlock();
-        }
-    }
-
-    void notifyEntityOwnershipListener(final DOMEntity entity, final boolean wasOwner, final boolean isOwner,
-            final boolean hasOwner, final DOMEntityOwnershipListener listener) {
-        listenerLock.readLock().lock();
-        try {
-            notifyListeners(entity, wasOwner, isOwner, hasOwner, ImmutableList.of(listenerActorMap.get(listener)));
-        } finally {
-            listenerLock.readLock().unlock();
-        }
-    }
-
-    @Holding("listenerLock")
-    private void notifyListeners(final DOMEntity entity, final boolean wasOwner, final boolean isOwner,
-            final boolean hasOwner, final Collection<ListenerActorRefEntry> listenerEntries) {
-        DOMEntityOwnershipChange changed = new DOMEntityOwnershipChange(entity,
-                EntityOwnershipChangeState.from(wasOwner, isOwner, hasOwner), inJeopardy);
-        for (ListenerActorRefEntry entry: listenerEntries) {
-            ActorRef listenerActor = entry.actorFor();
-
-            LOG.debug("{}: Notifying EntityOwnershipListenerActor {} with {}", logId, listenerActor, changed);
-
-            listenerActor.tell(changed, ActorRef.noSender());
-        }
-    }
-
-    private class ListenerActorRefEntry {
-        final DOMEntityOwnershipListener listener;
-
-        @GuardedBy("listenerLock")
-        ActorRef actorRef;
-
-        @GuardedBy("listenerLock")
-        int referenceCount = 1;
-
-        ListenerActorRefEntry(final DOMEntityOwnershipListener listener) {
-            this.listener = listener;
-        }
-
-        ActorRef actorFor() {
-            if (actorRef == null) {
-                actorRef = actorContext.actorOf(EntityOwnershipListenerActor.props(listener));
-
-                LOG.debug("{}: Created EntityOwnershipListenerActor {} for listener {}", logId, actorRef, listener);
-            }
-
-            return actorRef;
-        }
-
-        @Override
-        public String toString() {
-            return "ListenerActorRefEntry [actorRef=" + actorRef + ", referenceCount=" + referenceCount + "]";
-        }
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/EntityOwnershipShard.java b/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/EntityOwnershipShard.java
deleted file mode 100644 (file)
index 64d497b..0000000
+++ /dev/null
@@ -1,712 +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.entityownership;
-
-import static java.util.Objects.requireNonNull;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.CANDIDATE_NAME_NODE_ID;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.CANDIDATE_NODE_ID;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.ENTITY_ID_NODE_ID;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.ENTITY_ID_QNAME;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.ENTITY_NODE_ID;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.ENTITY_OWNERS_PATH;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.ENTITY_OWNER_NODE_ID;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.ENTITY_OWNER_QNAME;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.ENTITY_TYPES_PATH;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.ENTITY_TYPE_NODE_ID;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.ENTITY_TYPE_QNAME;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.candidateNodeKey;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.candidatePath;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.entityOwnersWithCandidate;
-
-import akka.actor.ActorRef;
-import akka.actor.ActorSelection;
-import akka.actor.Cancellable;
-import akka.cluster.Cluster;
-import akka.cluster.ClusterEvent.CurrentClusterState;
-import akka.cluster.Member;
-import akka.cluster.MemberStatus;
-import akka.pattern.Patterns;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-import org.opendaylight.controller.cluster.access.concepts.MemberName;
-import org.opendaylight.controller.cluster.datastore.DatastoreContext;
-import org.opendaylight.controller.cluster.datastore.Shard;
-import org.opendaylight.controller.cluster.datastore.identifiers.ShardIdentifier;
-import org.opendaylight.controller.cluster.datastore.messages.BatchedModifications;
-import org.opendaylight.controller.cluster.datastore.messages.PeerDown;
-import org.opendaylight.controller.cluster.datastore.messages.PeerUp;
-import org.opendaylight.controller.cluster.datastore.messages.SuccessReply;
-import org.opendaylight.controller.cluster.datastore.modification.DeleteModification;
-import org.opendaylight.controller.cluster.datastore.modification.MergeModification;
-import org.opendaylight.controller.cluster.datastore.modification.Modification;
-import org.opendaylight.controller.cluster.datastore.modification.WriteModification;
-import org.opendaylight.controller.cluster.entityownership.messages.CandidateAdded;
-import org.opendaylight.controller.cluster.entityownership.messages.CandidateRemoved;
-import org.opendaylight.controller.cluster.entityownership.messages.RegisterCandidateLocal;
-import org.opendaylight.controller.cluster.entityownership.messages.RegisterListenerLocal;
-import org.opendaylight.controller.cluster.entityownership.messages.RemoveAllCandidates;
-import org.opendaylight.controller.cluster.entityownership.messages.SelectOwner;
-import org.opendaylight.controller.cluster.entityownership.messages.UnregisterCandidateLocal;
-import org.opendaylight.controller.cluster.entityownership.messages.UnregisterListenerLocal;
-import org.opendaylight.controller.cluster.entityownership.selectionstrategy.EntityOwnerSelectionStrategy;
-import org.opendaylight.controller.cluster.entityownership.selectionstrategy.EntityOwnerSelectionStrategyConfig;
-import org.opendaylight.controller.cluster.raft.RaftState;
-import org.opendaylight.controller.cluster.raft.VotingState;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntity;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-import scala.concurrent.Future;
-import scala.concurrent.duration.FiniteDuration;
-
-/**
- * Special Shard for EntityOwnership.
- *
- * @author Thomas Pantelis
- */
-class EntityOwnershipShard extends Shard {
-    private final MemberName localMemberName;
-    private final EntityOwnershipShardCommitCoordinator commitCoordinator;
-    private final EntityOwnershipListenerSupport listenerSupport;
-    private final Set<MemberName> downPeerMemberNames = new HashSet<>();
-    private final EntityOwnerSelectionStrategyConfig strategyConfig;
-    private final Map<YangInstanceIdentifier, Cancellable> entityToScheduledOwnershipTask = new HashMap<>();
-    private final EntityOwnershipStatistics entityOwnershipStatistics;
-    private boolean removeAllInitialCandidates = true;
-
-    protected EntityOwnershipShard(final Builder builder) {
-        super(builder);
-        this.localMemberName = builder.localMemberName;
-        this.commitCoordinator = new EntityOwnershipShardCommitCoordinator(builder.localMemberName, LOG);
-        this.listenerSupport = new EntityOwnershipListenerSupport(getContext(), persistenceId());
-        this.strategyConfig = builder.ownerSelectionStrategyConfig;
-        this.entityOwnershipStatistics = new EntityOwnershipStatistics();
-        this.entityOwnershipStatistics.init(getDataStore());
-    }
-
-    private static DatastoreContext noPersistenceDatastoreContext(final DatastoreContext datastoreContext) {
-        return DatastoreContext.newBuilderFrom(datastoreContext).persistent(false).build();
-    }
-
-    @Override
-    protected void onDatastoreContext(final DatastoreContext context) {
-        super.onDatastoreContext(noPersistenceDatastoreContext(context));
-    }
-
-    @Override
-    protected void onRecoveryComplete() {
-        super.onRecoveryComplete();
-
-        new CandidateListChangeListener(getSelf(), persistenceId()).init(getDataStore());
-        new EntityOwnerChangeListener(localMemberName, listenerSupport).init(getDataStore());
-    }
-
-    @Override
-    public void handleNonRaftCommand(final Object message) {
-        if (message instanceof RegisterCandidateLocal) {
-            onRegisterCandidateLocal((RegisterCandidateLocal) message);
-        } else if (message instanceof UnregisterCandidateLocal) {
-            onUnregisterCandidateLocal((UnregisterCandidateLocal) message);
-        } else if (message instanceof CandidateAdded) {
-            onCandidateAdded((CandidateAdded) message);
-        } else if (message instanceof CandidateRemoved) {
-            onCandidateRemoved((CandidateRemoved) message);
-        } else if (message instanceof PeerDown) {
-            onPeerDown((PeerDown) message);
-        } else if (message instanceof PeerUp) {
-            onPeerUp((PeerUp) message);
-        } else if (message instanceof RegisterListenerLocal) {
-            onRegisterListenerLocal((RegisterListenerLocal) message);
-        } else if (message instanceof UnregisterListenerLocal) {
-            onUnregisterListenerLocal((UnregisterListenerLocal) message);
-        } else if (message instanceof SelectOwner) {
-            onSelectOwner((SelectOwner) message);
-        } else if (message instanceof RemoveAllCandidates) {
-            onRemoveAllCandidates((RemoveAllCandidates) message);
-        } else if (!commitCoordinator.handleMessage(message, this)) {
-            super.handleNonRaftCommand(message);
-        }
-    }
-
-    private void onRemoveAllCandidates(final RemoveAllCandidates message) {
-        LOG.debug("{}: onRemoveAllCandidates: {}", persistenceId(), message);
-
-        removeCandidateFromEntities(message.getMemberName());
-    }
-
-    private void onSelectOwner(final SelectOwner selectOwner) {
-        LOG.debug("{}: onSelectOwner: {}", persistenceId(), selectOwner);
-
-        String currentOwner = getCurrentOwner(selectOwner.getEntityPath());
-        if (Strings.isNullOrEmpty(currentOwner)) {
-            writeNewOwner(selectOwner.getEntityPath(), newOwner(currentOwner, selectOwner.getAllCandidates(),
-                    selectOwner.getOwnerSelectionStrategy()));
-
-            Cancellable cancellable = entityToScheduledOwnershipTask.get(selectOwner.getEntityPath());
-            if (cancellable != null) {
-                if (!cancellable.isCancelled()) {
-                    cancellable.cancel();
-                }
-                entityToScheduledOwnershipTask.remove(selectOwner.getEntityPath());
-            }
-        }
-    }
-
-    private void onRegisterCandidateLocal(final RegisterCandidateLocal registerCandidate) {
-        LOG.debug("{}: onRegisterCandidateLocal: {}", persistenceId(), registerCandidate);
-
-        NormalizedNode entityOwners = entityOwnersWithCandidate(registerCandidate.getEntity().getType(),
-                registerCandidate.getEntity().getIdentifier(), localMemberName.getName());
-        commitCoordinator.commitModification(new MergeModification(ENTITY_OWNERS_PATH, entityOwners), this);
-
-        getSender().tell(SuccessReply.INSTANCE, getSelf());
-    }
-
-    private void onUnregisterCandidateLocal(final UnregisterCandidateLocal unregisterCandidate) {
-        LOG.debug("{}: onUnregisterCandidateLocal: {}", persistenceId(), unregisterCandidate);
-
-        DOMEntity entity = unregisterCandidate.getEntity();
-        YangInstanceIdentifier candidatePath = candidatePath(entity.getType(), entity.getIdentifier(),
-                localMemberName.getName());
-        commitCoordinator.commitModification(new DeleteModification(candidatePath), this);
-
-        getSender().tell(SuccessReply.INSTANCE, getSelf());
-    }
-
-    private void onRegisterListenerLocal(final RegisterListenerLocal registerListener) {
-        LOG.debug("{}: onRegisterListenerLocal: {}", persistenceId(), registerListener);
-
-        listenerSupport.addEntityOwnershipListener(registerListener.getEntityType(), registerListener.getListener());
-
-        getSender().tell(SuccessReply.INSTANCE, getSelf());
-
-        searchForEntities((entityTypeNode, entityNode) -> {
-            String entityType = entityTypeNode.findChildByArg(ENTITY_TYPE_NODE_ID)
-                .map(child -> child.body().toString())
-                .orElse(null);
-            if (registerListener.getEntityType().equals(entityType)) {
-                final boolean hasOwner;
-                final boolean isOwner;
-
-                Optional<DataContainerChild> possibleOwner = entityNode.findChildByArg(ENTITY_OWNER_NODE_ID);
-                if (possibleOwner.isPresent()) {
-                    isOwner = localMemberName.getName().equals(possibleOwner.get().body().toString());
-                    hasOwner = true;
-                } else {
-                    isOwner = false;
-                    hasOwner = false;
-                }
-
-                DOMEntity entity = new DOMEntity(entityType,
-                    (YangInstanceIdentifier) entityNode.findChildByArg(ENTITY_ID_NODE_ID).get().body());
-
-                listenerSupport.notifyEntityOwnershipListener(entity, false, isOwner, hasOwner,
-                    registerListener.getListener());
-            }
-        });
-    }
-
-    private void onUnregisterListenerLocal(final UnregisterListenerLocal unregisterListener) {
-        LOG.debug("{}: onUnregisterListenerLocal: {}", persistenceId(), unregisterListener);
-
-        listenerSupport.removeEntityOwnershipListener(unregisterListener.getEntityType(),
-                unregisterListener.getListener());
-
-        getSender().tell(SuccessReply.INSTANCE, getSelf());
-    }
-
-    void tryCommitModifications(final BatchedModifications modifications) {
-        if (isLeader()) {
-            LOG.debug("{}: Committing BatchedModifications {} locally", persistenceId(),
-                    modifications.getTransactionId());
-
-            // Note that it's possible the commit won't get consensus and will timeout and not be applied
-            // to the state. However we don't need to retry it in that case b/c it will be committed to
-            // the journal first and, once a majority of followers come back on line and it is replicated,
-            // it will be applied at that point.
-            handleBatchedModificationsLocal(modifications, self());
-        } else {
-            final ActorSelection leader = getLeader();
-            if (leader != null) {
-                possiblyRemoveAllInitialCandidates(leader);
-
-                LOG.debug("{}: Sending BatchedModifications {} to leader {}", persistenceId(),
-                        modifications.getTransactionId(), leader);
-
-                Future<Object> future = Patterns.ask(leader, modifications, TimeUnit.SECONDS.toMillis(
-                        getDatastoreContext().getShardTransactionCommitTimeoutInSeconds()));
-
-                Patterns.pipe(future, getContext().dispatcher()).pipeTo(getSelf(), ActorRef.noSender());
-            }
-        }
-    }
-
-    void possiblyRemoveAllInitialCandidates(final ActorSelection leader) {
-        // The following handles removing all candidates on startup when re-joining with a remote leader. When a
-        // follower is detected as down, the leader will re-assign new owners to entities that were owned by the
-        // down member but doesn't remove the down member as a candidate, as the down node may actually be isolated
-        // and still running. Therefore on startup we send an initial message to the remote leader to remove any
-        // potential stale candidates we had previously registered, as it's possible a candidate may not be
-        // registered by a client in the new incarnation. We have to send the RemoveAllCandidates message prior to any
-        // pending registrations.
-        if (removeAllInitialCandidates && leader != null) {
-            removeAllInitialCandidates = false;
-            if (!isLeader()) {
-                LOG.debug("{} - got new leader {} on startup - sending RemoveAllCandidates", persistenceId(), leader);
-
-                leader.tell(new RemoveAllCandidates(localMemberName), ActorRef.noSender());
-            }
-        }
-    }
-
-    boolean hasLeader() {
-        return getLeader() != null && (!isLeader() || isLeaderActive());
-    }
-
-    /**
-     * Determine if we are in jeopardy based on observed RAFT state.
-     */
-    private static boolean inJeopardy(final RaftState state) {
-        switch (state) {
-            case Candidate:
-            case Follower:
-            case Leader:
-            case PreLeader:
-                return false;
-            case IsolatedLeader:
-                return true;
-            default:
-                throw new IllegalStateException("Unsupported RAFT state " + state);
-        }
-    }
-
-    private void notifyAllListeners() {
-        searchForEntities((entityTypeNode, entityNode) -> {
-            Optional<DataContainerChild> possibleType = entityTypeNode.findChildByArg(ENTITY_TYPE_NODE_ID);
-            if (possibleType.isPresent()) {
-                final boolean hasOwner;
-                final boolean isOwner;
-
-                Optional<DataContainerChild> possibleOwner = entityNode.findChildByArg(ENTITY_OWNER_NODE_ID);
-                if (possibleOwner.isPresent()) {
-                    isOwner = localMemberName.getName().equals(possibleOwner.get().body().toString());
-                    hasOwner = true;
-                } else {
-                    isOwner = false;
-                    hasOwner = false;
-                }
-
-                DOMEntity entity = new DOMEntity(possibleType.get().body().toString(),
-                    (YangInstanceIdentifier) entityNode.findChildByArg(ENTITY_ID_NODE_ID).get().body());
-
-                listenerSupport.notifyEntityOwnershipListeners(entity, isOwner, isOwner, hasOwner);
-            }
-        });
-    }
-
-    @Override
-    protected void onStateChanged() {
-        boolean isLeader = isLeader();
-        LOG.debug("{}: onStateChanged: isLeader: {}, hasLeader: {}", persistenceId(), isLeader, hasLeader());
-
-        // Examine current RAFT state to see if we are in jeopardy, potentially notifying all listeners
-        final boolean inJeopardy = inJeopardy(getRaftState());
-        final boolean wasInJeopardy = listenerSupport.setInJeopardy(inJeopardy);
-        if (inJeopardy != wasInJeopardy) {
-            LOG.debug("{}: {} jeopardy state, notifying all listeners", persistenceId(),
-                inJeopardy ? "entered" : "left");
-            notifyAllListeners();
-        }
-
-        commitCoordinator.onStateChanged(this, isLeader);
-
-        super.onStateChanged();
-    }
-
-    @Override
-    protected void onLeaderChanged(final String oldLeader, final String newLeader) {
-        boolean isLeader = isLeader();
-        LOG.debug("{}: onLeaderChanged: oldLeader: {}, newLeader: {}, isLeader: {}", persistenceId(), oldLeader,
-                newLeader, isLeader);
-
-        if (isLeader) {
-
-            // Re-initialize the downPeerMemberNames from the current akka Cluster state. The previous leader, if any,
-            // is most likely down however it's possible we haven't received the PeerDown message yet.
-            initializeDownPeerMemberNamesFromClusterState();
-
-            // Clear all existing strategies so that they get re-created when we call createStrategy again
-            // This allows the strategies to be re-initialized with existing statistics maintained by
-            // EntityOwnershipStatistics
-            strategyConfig.clearStrategies();
-
-            // Re-assign owners for all members that are known to be down. In a cluster which has greater than
-            // 3 nodes it is possible for some node beside the leader being down when the leadership transitions
-            // it makes sense to use this event to re-assign owners for those downed nodes.
-            Set<String> ownedBy = new HashSet<>(downPeerMemberNames.size() + 1);
-            for (MemberName downPeerName : downPeerMemberNames) {
-                ownedBy.add(downPeerName.getName());
-            }
-
-            // Also try to assign owners for entities that have no current owner. See explanation in onPeerUp.
-            ownedBy.add("");
-            selectNewOwnerForEntitiesOwnedBy(ownedBy);
-        } else {
-            // The leader changed - notify the coordinator to check if pending modifications need to be sent.
-            // While onStateChanged also does this, this method handles the case where the shard hears from a
-            // leader and stays in the follower state. In that case no behavior state change occurs.
-            commitCoordinator.onStateChanged(this, isLeader);
-        }
-
-        super.onLeaderChanged(oldLeader, newLeader);
-    }
-
-    @Override
-    protected void onVotingStateChangeComplete() {
-        // Re-evaluate ownership for all entities - if a member changed from voting to non-voting it should lose
-        // ownership and vice versa it now is a candidate to become owner.
-        final List<Modification> modifications = new ArrayList<>();
-        searchForEntities((entityTypeNode, entityNode) -> {
-            YangInstanceIdentifier entityPath = YangInstanceIdentifier.builder(ENTITY_TYPES_PATH)
-                    .node(entityTypeNode.getIdentifier()).node(ENTITY_NODE_ID).node(entityNode.getIdentifier())
-                    .node(ENTITY_OWNER_NODE_ID).build();
-
-            Optional<String> possibleOwner =
-                    entityNode.findChildByArg(ENTITY_OWNER_NODE_ID).map(node -> node.body().toString());
-            String newOwner = newOwner(possibleOwner.orElse(null), getCandidateNames(entityNode),
-                    getEntityOwnerElectionStrategy(entityPath));
-
-            if (!newOwner.equals(possibleOwner.orElse(""))) {
-                modifications.add(new WriteModification(entityPath,
-                        ImmutableNodes.leafNode(ENTITY_OWNER_NODE_ID, newOwner)));
-            }
-        });
-
-        commitCoordinator.commitModifications(modifications, this);
-    }
-
-    private void initializeDownPeerMemberNamesFromClusterState() {
-        Optional<Cluster> cluster = getRaftActorContext().getCluster();
-        if (!cluster.isPresent()) {
-            return;
-        }
-
-        CurrentClusterState state = cluster.get().state();
-        Set<Member> unreachable = state.getUnreachable();
-
-        LOG.debug(
-            "{}: initializeDownPeerMemberNamesFromClusterState - current downPeerMemberNames: {}, unreachable: {}",
-            persistenceId(), downPeerMemberNames, unreachable);
-
-        downPeerMemberNames.clear();
-        for (Member m: unreachable) {
-            downPeerMemberNames.add(MemberName.forName(m.getRoles().iterator().next()));
-        }
-
-        for (Member m: state.getMembers()) {
-            if (m.status() != MemberStatus.up() && m.status() != MemberStatus.weaklyUp()) {
-                LOG.debug("{}: Adding down member with status {}", persistenceId(), m.status());
-                downPeerMemberNames.add(MemberName.forName(m.getRoles().iterator().next()));
-            }
-        }
-
-        LOG.debug("{}: new downPeerMemberNames: {}", persistenceId(), downPeerMemberNames);
-    }
-
-    private void onCandidateRemoved(final CandidateRemoved message) {
-        LOG.debug("{}: onCandidateRemoved: {}", persistenceId(), message);
-
-        if (isLeader()) {
-            String currentOwner = getCurrentOwner(message.getEntityPath());
-            writeNewOwner(message.getEntityPath(),
-                    newOwner(currentOwner, message.getRemainingCandidates(),
-                            getEntityOwnerElectionStrategy(message.getEntityPath())));
-        }
-    }
-
-    private EntityOwnerSelectionStrategy getEntityOwnerElectionStrategy(final YangInstanceIdentifier entityPath) {
-        final String entityType = EntityOwnersModel.entityTypeFromEntityPath(entityPath);
-        return strategyConfig.createStrategy(entityType, entityOwnershipStatistics.byEntityType(entityType));
-    }
-
-    private void onCandidateAdded(final CandidateAdded message) {
-        if (!isLeader()) {
-            return;
-        }
-
-        LOG.debug("{}: onCandidateAdded: {}", persistenceId(), message);
-
-        // Since a node's candidate member is only added by the node itself, we can assume the node is up so
-        // remove it from the downPeerMemberNames.
-        downPeerMemberNames.remove(MemberName.forName(message.getNewCandidate()));
-
-        final String currentOwner = getCurrentOwner(message.getEntityPath());
-        final EntityOwnerSelectionStrategy strategy = getEntityOwnerElectionStrategy(message.getEntityPath());
-
-        // Available members is all the known peers - the number of peers that are down + self
-        // So if there are 2 peers and 1 is down then availableMembers will be 2
-        final int availableMembers = getRaftActorContext().getPeerIds().size() - downPeerMemberNames.size() + 1;
-
-        LOG.debug("{}: Using strategy {} to select owner, currentOwner = {}", persistenceId(), strategy, currentOwner);
-
-        if (strategy.getSelectionDelayInMillis() == 0L) {
-            writeNewOwner(message.getEntityPath(), newOwner(currentOwner, message.getAllCandidates(),
-                    strategy));
-        } else if (message.getAllCandidates().size() == availableMembers) {
-            LOG.debug("{}: Received the maximum candidates requests : {} writing new owner",
-                    persistenceId(), availableMembers);
-            cancelOwnerSelectionTask(message.getEntityPath());
-            writeNewOwner(message.getEntityPath(), newOwner(currentOwner, message.getAllCandidates(),
-                    strategy));
-        } else {
-            scheduleOwnerSelection(message.getEntityPath(), message.getAllCandidates(), strategy);
-        }
-    }
-
-    private void onPeerDown(final PeerDown peerDown) {
-        LOG.info("{}: onPeerDown: {}", persistenceId(), peerDown);
-
-        MemberName downMemberName = peerDown.getMemberName();
-        if (downPeerMemberNames.add(downMemberName) && isLeader()) {
-            // Select new owners for entities owned by the down peer and which have other candidates. For an entity for
-            // which the down peer is the only candidate, we leave it as the owner and don't clear it. This is done to
-            // handle the case where the peer member process is actually still running but the node is partitioned.
-            // When the partition is healed, the peer just remains as the owner. If the peer process actually restarted,
-            // it will first remove all its candidates on startup. If another candidate is registered during the time
-            // the peer is down, the new candidate will be selected as the new owner.
-
-            selectNewOwnerForEntitiesOwnedBy(ImmutableSet.of(downMemberName.getName()));
-        }
-    }
-
-    private void selectNewOwnerForEntitiesOwnedBy(final Set<String> ownedBy) {
-        final List<Modification> modifications = new ArrayList<>();
-        searchForEntitiesOwnedBy(ownedBy, (entityTypeNode, entityNode) -> {
-            YangInstanceIdentifier entityPath = YangInstanceIdentifier.builder(ENTITY_TYPES_PATH)
-                    .node(entityTypeNode.getIdentifier()).node(ENTITY_NODE_ID).node(entityNode.getIdentifier())
-                    .node(ENTITY_OWNER_NODE_ID).build();
-            String newOwner = newOwner(getCurrentOwner(entityPath), getCandidateNames(entityNode),
-                    getEntityOwnerElectionStrategy(entityPath));
-
-            if (!newOwner.isEmpty()) {
-                LOG.debug("{}: Found entity {}, writing new owner {}", persistenceId(), entityPath, newOwner);
-
-                modifications.add(new WriteModification(entityPath,
-                    ImmutableNodes.leafNode(ENTITY_OWNER_NODE_ID, newOwner)));
-
-            } else {
-                LOG.debug("{}: Found entity {} but no other candidates - not clearing owner", persistenceId(),
-                        entityPath);
-            }
-        });
-
-        commitCoordinator.commitModifications(modifications, this);
-    }
-
-    private void onPeerUp(final PeerUp peerUp) {
-        LOG.debug("{}: onPeerUp: {}", persistenceId(), peerUp);
-
-        downPeerMemberNames.remove(peerUp.getMemberName());
-
-        // Notify the coordinator to check if pending modifications need to be sent. We do this here
-        // to handle the case where the leader's peer address isn't known yet when a prior state or
-        // leader change occurred.
-        commitCoordinator.onStateChanged(this, isLeader());
-
-        if (isLeader()) {
-            // Try to assign owners for entities that have no current owner. It's possible the peer that is now up
-            // had previously registered as a candidate and was the only candidate but the owner write tx couldn't be
-            // committed due to a leader change. Eg, the leader is able to successfully commit the candidate add tx but
-            // becomes isolated before it can commit the owner change and switches to follower. The majority partition
-            // with a new leader has the candidate but the entity has no owner. When the partition is healed and the
-            // previously isolated leader reconnects, we'll receive onPeerUp and, if there's still no owner, the
-            // previous leader will gain ownership.
-            selectNewOwnerForEntitiesOwnedBy(ImmutableSet.of(""));
-        }
-    }
-
-    private static Collection<String> getCandidateNames(final MapEntryNode entity) {
-        return entity.findChildByArg(CANDIDATE_NODE_ID).map(child -> {
-            Collection<MapEntryNode> candidates = ((MapNode) child).body();
-            Collection<String> candidateNames = new ArrayList<>(candidates.size());
-            for (MapEntryNode candidate: candidates) {
-                candidateNames.add(candidate.findChildByArg(CANDIDATE_NAME_NODE_ID).get().body().toString());
-            }
-            return candidateNames;
-        }).orElse(ImmutableList.of());
-    }
-
-    private void searchForEntitiesOwnedBy(final Set<String> ownedBy, final EntityWalker walker) {
-        LOG.debug("{}: Searching for entities owned by {}", persistenceId(), ownedBy);
-
-        searchForEntities((entityTypeNode, entityNode) -> {
-            String currentOwner = entityNode.findChildByArg(ENTITY_OWNER_NODE_ID)
-                .map(child -> child.body().toString())
-                .orElse("");
-            if (ownedBy.contains(currentOwner)) {
-                walker.onEntity(entityTypeNode, entityNode);
-            }
-        });
-    }
-
-    private void removeCandidateFromEntities(final MemberName member) {
-        final List<Modification> modifications = new ArrayList<>();
-        searchForEntities((entityTypeNode, entityNode) -> {
-            if (hasCandidate(entityNode, member)) {
-                YangInstanceIdentifier entityId = (YangInstanceIdentifier) entityNode.getIdentifier()
-                        .getValue(ENTITY_ID_QNAME);
-                YangInstanceIdentifier candidatePath = candidatePath(entityTypeNode.getIdentifier()
-                    .getValue(ENTITY_TYPE_QNAME).toString(), entityId, member.getName());
-
-                LOG.info("{}: Found entity {}, removing candidate {}, path {}", persistenceId(), entityId,
-                        member, candidatePath);
-
-                modifications.add(new DeleteModification(candidatePath));
-            }
-        });
-
-        commitCoordinator.commitModifications(modifications, this);
-    }
-
-    private static boolean hasCandidate(final MapEntryNode entity, final MemberName candidateName) {
-        return entity.findChildByArg(CANDIDATE_NODE_ID)
-                .flatMap(child -> ((MapNode)child).findChildByArg(candidateNodeKey(candidateName.getName())))
-                .isPresent();
-    }
-
-    private void searchForEntities(final EntityWalker walker) {
-        Optional<NormalizedNode> possibleEntityTypes = getDataStore().readNode(ENTITY_TYPES_PATH);
-        if (!possibleEntityTypes.isPresent()) {
-            return;
-        }
-
-        for (MapEntryNode entityType : ((MapNode) possibleEntityTypes.get()).body()) {
-            Optional<DataContainerChild> possibleEntities = entityType.findChildByArg(ENTITY_NODE_ID);
-            if (!possibleEntities.isPresent()) {
-                // shouldn't happen but handle anyway
-                continue;
-            }
-
-            for (MapEntryNode entity:  ((MapNode) possibleEntities.get()).body()) {
-                walker.onEntity(entityType, entity);
-            }
-        }
-    }
-
-    private void writeNewOwner(final YangInstanceIdentifier entityPath, final String newOwner) {
-        LOG.debug("{}: Writing new owner {} for entity {}", persistenceId(), newOwner, entityPath);
-
-        commitCoordinator.commitModification(new WriteModification(entityPath.node(ENTITY_OWNER_QNAME),
-                ImmutableNodes.leafNode(ENTITY_OWNER_NODE_ID, newOwner)), this);
-    }
-
-    /**
-     * Schedule a new owner selection job. Cancelling any outstanding job if it has not been cancelled.
-     */
-    private void scheduleOwnerSelection(final YangInstanceIdentifier entityPath, final Collection<String> allCandidates,
-                                       final EntityOwnerSelectionStrategy strategy) {
-        cancelOwnerSelectionTask(entityPath);
-
-        LOG.debug("{}: Scheduling owner selection after {} ms", persistenceId(), strategy.getSelectionDelayInMillis());
-
-        final Cancellable lastScheduledTask = context().system().scheduler().scheduleOnce(
-                FiniteDuration.apply(strategy.getSelectionDelayInMillis(), TimeUnit.MILLISECONDS), self(),
-                new SelectOwner(entityPath, allCandidates, strategy), context().system().dispatcher(), self());
-
-        entityToScheduledOwnershipTask.put(entityPath, lastScheduledTask);
-    }
-
-    private void cancelOwnerSelectionTask(final YangInstanceIdentifier entityPath) {
-        final Cancellable lastScheduledTask = entityToScheduledOwnershipTask.get(entityPath);
-        if (lastScheduledTask != null && !lastScheduledTask.isCancelled()) {
-            lastScheduledTask.cancel();
-        }
-    }
-
-    private String newOwner(final String currentOwner, final Collection<String> candidates,
-            final EntityOwnerSelectionStrategy ownerSelectionStrategy) {
-        Collection<String> viableCandidates = getViableCandidates(candidates);
-        if (viableCandidates.isEmpty()) {
-            return "";
-        }
-        return ownerSelectionStrategy.newOwner(currentOwner, viableCandidates);
-    }
-
-    private Collection<String> getViableCandidates(final Collection<String> candidates) {
-        Map<MemberName, VotingState> memberToVotingState = new HashMap<>();
-        getRaftActorContext().getPeers().forEach(peerInfo -> memberToVotingState.put(
-                ShardIdentifier.fromShardIdString(peerInfo.getId()).getMemberName(), peerInfo.getVotingState()));
-
-        Collection<String> viableCandidates = new ArrayList<>();
-
-        for (String candidate : candidates) {
-            MemberName memberName = MemberName.forName(candidate);
-            if (memberToVotingState.get(memberName) != VotingState.NON_VOTING
-                    && !downPeerMemberNames.contains(memberName)) {
-                viableCandidates.add(candidate);
-            }
-        }
-        return viableCandidates;
-    }
-
-    private String getCurrentOwner(final YangInstanceIdentifier entityId) {
-        return getDataStore().readNode(entityId.node(ENTITY_OWNER_QNAME))
-                .map(owner -> owner.body().toString())
-                .orElse(null);
-    }
-
-    @FunctionalInterface
-    private interface EntityWalker {
-        void onEntity(MapEntryNode entityTypeNode, MapEntryNode entityNode);
-    }
-
-    public static Builder newBuilder() {
-        return new Builder();
-    }
-
-    static class Builder extends Shard.AbstractBuilder<Builder, EntityOwnershipShard> {
-        private MemberName localMemberName;
-        private EntityOwnerSelectionStrategyConfig ownerSelectionStrategyConfig;
-
-        protected Builder() {
-            super(EntityOwnershipShard.class);
-        }
-
-        Builder localMemberName(final MemberName newLocalMemberName) {
-            checkSealed();
-            this.localMemberName = newLocalMemberName;
-            return this;
-        }
-
-        Builder ownerSelectionStrategyConfig(final EntityOwnerSelectionStrategyConfig newOwnerSelectionStrategyConfig) {
-            checkSealed();
-            this.ownerSelectionStrategyConfig = newOwnerSelectionStrategyConfig;
-            return this;
-        }
-
-        @Override
-        protected void verify() {
-            super.verify();
-            requireNonNull(localMemberName, "localMemberName should not be null");
-            requireNonNull(ownerSelectionStrategyConfig, "ownerSelectionStrategyConfig should not be null");
-        }
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/EntityOwnershipShardCommitCoordinator.java b/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/EntityOwnershipShardCommitCoordinator.java
deleted file mode 100644 (file)
index 3402b23..0000000
+++ /dev/null
@@ -1,277 +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.entityownership;
-
-import static java.util.Objects.requireNonNull;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.ENTITY_OWNER_QNAME;
-
-import akka.actor.ActorRef;
-import akka.actor.Cancellable;
-import akka.actor.Status.Failure;
-import com.google.common.collect.ImmutableList;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Queue;
-import org.eclipse.jdt.annotation.Nullable;
-import org.opendaylight.controller.cluster.access.concepts.ClientIdentifier;
-import org.opendaylight.controller.cluster.access.concepts.FrontendIdentifier;
-import org.opendaylight.controller.cluster.access.concepts.FrontendType;
-import org.opendaylight.controller.cluster.access.concepts.LocalHistoryIdentifier;
-import org.opendaylight.controller.cluster.access.concepts.MemberName;
-import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
-import org.opendaylight.controller.cluster.datastore.DataStoreVersions;
-import org.opendaylight.controller.cluster.datastore.exceptions.NoShardLeaderException;
-import org.opendaylight.controller.cluster.datastore.messages.BatchedModifications;
-import org.opendaylight.controller.cluster.datastore.messages.CommitTransactionReply;
-import org.opendaylight.controller.cluster.datastore.modification.Modification;
-import org.opendaylight.controller.cluster.datastore.modification.WriteModification;
-import org.slf4j.Logger;
-import scala.concurrent.duration.FiniteDuration;
-
-/**
- * Handles commits and retries for the EntityOwnershipShard.
- *
- * @author Thomas Pantelis
- */
-class EntityOwnershipShardCommitCoordinator {
-    private static final Object COMMIT_RETRY_MESSAGE = new Object() {
-        @Override
-        public String toString() {
-            return "entityCommitRetry";
-        }
-    };
-    private static final FrontendType FRONTEND_TYPE = FrontendType.forName("entity-ownership-internal");
-
-    private final Queue<Modification> pendingModifications = new LinkedList<>();
-    private final LocalHistoryIdentifier historyId;
-    private final Logger log;
-
-    private BatchedModifications inflightCommit;
-    private Cancellable retryCommitSchedule;
-    private long transactionIDCounter = 0;
-
-    EntityOwnershipShardCommitCoordinator(final MemberName localMemberName, final Logger log) {
-        this.log = requireNonNull(log);
-        historyId = new LocalHistoryIdentifier(
-                ClientIdentifier.create(FrontendIdentifier.create(localMemberName, FRONTEND_TYPE), 0), 0);
-    }
-
-    boolean handleMessage(final Object message, final EntityOwnershipShard shard) {
-        boolean handled = true;
-        if (CommitTransactionReply.isSerializedType(message)) {
-            // Successful reply from a local commit.
-            inflightCommitSucceeded(shard);
-        } else if (message instanceof akka.actor.Status.Failure) {
-            // Failure reply from a local commit.
-            inflightCommitFailure(((Failure) message).cause(), shard);
-        } else if (COMMIT_RETRY_MESSAGE.equals(message)) {
-            retryInflightCommit(shard);
-        } else {
-            handled = false;
-        }
-
-        return handled;
-    }
-
-    private void retryInflightCommit(final EntityOwnershipShard shard) {
-        // Shouldn't be null happen but verify anyway
-        if (inflightCommit == null) {
-            return;
-        }
-
-        if (shard.hasLeader()) {
-            log.debug("Retrying commit for BatchedModifications {}", inflightCommit.getTransactionId());
-
-            shard.tryCommitModifications(inflightCommit);
-        } else {
-            scheduleInflightCommitRetry(shard);
-        }
-    }
-
-    void inflightCommitFailure(final Throwable cause, final EntityOwnershipShard shard) {
-        // This should've originated from a failed inflight commit but verify anyway
-        if (inflightCommit == null) {
-            return;
-        }
-
-        log.debug("Inflight BatchedModifications {} commit failed", inflightCommit.getTransactionId(), cause);
-
-        if (!(cause instanceof NoShardLeaderException)) {
-            // If the failure is other than NoShardLeaderException the commit may have been partially
-            // processed so retry with a new transaction ID to be safe.
-            newInflightCommitWithDifferentTransactionID();
-        }
-
-        scheduleInflightCommitRetry(shard);
-    }
-
-    private void scheduleInflightCommitRetry(final EntityOwnershipShard shard) {
-        FiniteDuration duration = shard.getDatastoreContext().getShardRaftConfig().getElectionTimeOutInterval();
-
-        log.debug("Scheduling retry for BatchedModifications commit {} in {}",
-                inflightCommit.getTransactionId(), duration);
-
-        retryCommitSchedule = shard.getContext().system().scheduler().scheduleOnce(duration, shard.getSelf(),
-                COMMIT_RETRY_MESSAGE, shard.getContext().dispatcher(), ActorRef.noSender());
-    }
-
-    void inflightCommitSucceeded(final EntityOwnershipShard shard) {
-        // Shouldn't be null but verify anyway
-        if (inflightCommit == null) {
-            return;
-        }
-
-        if (retryCommitSchedule != null) {
-            retryCommitSchedule.cancel();
-        }
-
-        log.debug("BatchedModifications commit {} succeeded", inflightCommit.getTransactionId());
-
-        inflightCommit = null;
-        commitNextBatch(shard);
-    }
-
-    void commitNextBatch(final EntityOwnershipShard shard) {
-        if (inflightCommit != null || pendingModifications.isEmpty() || !shard.hasLeader()) {
-            return;
-        }
-
-        inflightCommit = newBatchedModifications();
-        Iterator<Modification> iter = pendingModifications.iterator();
-        while (iter.hasNext()) {
-            inflightCommit.addModification(iter.next());
-            iter.remove();
-            if (inflightCommit.getModifications().size()
-                    >= shard.getDatastoreContext().getShardBatchedModificationCount()) {
-                break;
-            }
-        }
-
-        log.debug("Committing next BatchedModifications {}, size {}", inflightCommit.getTransactionId(),
-                inflightCommit.getModifications().size());
-
-        shard.tryCommitModifications(inflightCommit);
-    }
-
-    void commitModification(final Modification modification, final EntityOwnershipShard shard) {
-        commitModifications(ImmutableList.of(modification), shard);
-    }
-
-    void commitModifications(final List<Modification> modifications, final EntityOwnershipShard shard) {
-        if (modifications.isEmpty()) {
-            return;
-        }
-
-        boolean hasLeader = shard.hasLeader();
-        if (inflightCommit != null || !hasLeader) {
-            if (log.isDebugEnabled()) {
-                log.debug("{} - adding modifications to pending",
-                        inflightCommit != null ? "A commit is inflight" : "No shard leader");
-            }
-
-            pendingModifications.addAll(modifications);
-        } else {
-            inflightCommit = newBatchedModifications();
-            inflightCommit.addModifications(modifications);
-            shard.tryCommitModifications(inflightCommit);
-        }
-    }
-
-    void onStateChanged(final EntityOwnershipShard shard, final boolean isLeader) {
-        shard.possiblyRemoveAllInitialCandidates(shard.getLeader());
-
-        possiblyPrunePendingCommits(shard, isLeader);
-
-        if (!isLeader && inflightCommit != null) {
-            // We're no longer the leader but we have an inflight local commit. This likely means we didn't get
-            // consensus for the commit and switched to follower due to another node with a higher term. We
-            // can't be sure if the commit was replicated to any node so we retry it here with a new
-            // transaction ID.
-            if (retryCommitSchedule != null) {
-                retryCommitSchedule.cancel();
-            }
-
-            newInflightCommitWithDifferentTransactionID();
-            retryInflightCommit(shard);
-        } else {
-            commitNextBatch(shard);
-        }
-    }
-
-    private void possiblyPrunePendingCommits(final EntityOwnershipShard shard, final boolean isLeader) {
-        // If we were the leader and transitioned to follower, we'll try to forward pending commits to the new leader.
-        // However certain commits, e.g. entity owner changes, should only be committed by a valid leader as the
-        // criteria used to determine the commit may be stale. Since we're no longer a valid leader, we should not
-        // forward such commits thus we prune the pending modifications. We still should forward local candidate change
-        // commits.
-        if (shard.hasLeader() && !isLeader) {
-            // We may have already submitted a transaction for replication and commit. We don't need the base Shard to
-            // forward it since we also have it stored in the inflightCommit and handle retries. So we just clear
-            // pending transactions and drop them.
-            shard.convertPendingTransactionsToMessages();
-
-            // Prune the inflightCommit.
-            if (inflightCommit != null) {
-                inflightCommit = pruneModifications(inflightCommit);
-            }
-
-            // Prune the subsequent pending modifications.
-            pendingModifications.removeIf(mod -> !canForwardModificationToNewLeader(mod));
-        }
-    }
-
-    private @Nullable BatchedModifications pruneModifications(final BatchedModifications toPrune) {
-        BatchedModifications prunedModifications = new BatchedModifications(toPrune.getTransactionId(),
-                toPrune.getVersion());
-        prunedModifications.setDoCommitOnReady(toPrune.isDoCommitOnReady());
-        if (toPrune.isReady()) {
-            prunedModifications.setReady(toPrune.getParticipatingShardNames());
-        }
-        prunedModifications.setTotalMessagesSent(toPrune.getTotalMessagesSent());
-        for (Modification mod: toPrune.getModifications()) {
-            if (canForwardModificationToNewLeader(mod)) {
-                prunedModifications.addModification(mod);
-            }
-        }
-
-        return !prunedModifications.getModifications().isEmpty() ? prunedModifications : null;
-    }
-
-    private boolean canForwardModificationToNewLeader(final Modification mod) {
-        // If this is a WRITE of entity owner we don't want to forward it to a new leader since the criteria used
-        // to determine the new owner might be stale.
-        if (mod instanceof WriteModification) {
-            WriteModification writeMod = (WriteModification)mod;
-            boolean canForward = !writeMod.getPath().getLastPathArgument().getNodeType().equals(ENTITY_OWNER_QNAME);
-
-            if (!canForward) {
-                log.debug("Not forwarding WRITE modification for {} to new leader", writeMod.getPath());
-            }
-
-            return canForward;
-        }
-
-        return true;
-    }
-
-    private void newInflightCommitWithDifferentTransactionID() {
-        BatchedModifications newBatchedModifications = newBatchedModifications();
-        newBatchedModifications.addModifications(inflightCommit.getModifications());
-        inflightCommit = newBatchedModifications;
-    }
-
-    private BatchedModifications newBatchedModifications() {
-        BatchedModifications modifications = new BatchedModifications(
-            new TransactionIdentifier(historyId, ++transactionIDCounter), DataStoreVersions.CURRENT_VERSION);
-        modifications.setDoCommitOnReady(true);
-        modifications.setReady();
-        modifications.setTotalMessagesSent(1);
-        return modifications;
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/EntityOwnershipStatistics.java b/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/EntityOwnershipStatistics.java
deleted file mode 100644 (file)
index 59cc755..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco 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.entityownership;
-
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.entityTypeFromEntityPath;
-
-import com.google.common.base.Strings;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
-import tech.pantheon.triemap.TrieMap;
-
-/**
- * EntityOwnershipStatistics is a utility class that keeps track of ownership statistics for the candidates and
- * caches it for quick count queries.
- * <p/>
- * While the entity ownership model does maintain the information about which entity is owned by which candidate
- * finding out how many entities of a given type are owned by a given candidate is not an efficient query.
- */
-class EntityOwnershipStatistics extends AbstractEntityOwnerChangeListener {
-    private final TrieMap<String, TrieMap<String, Long>> statistics = TrieMap.create();
-
-    EntityOwnershipStatistics() {
-        // Hidden on purpose
-    }
-
-    @Override
-    public void onInitialData() {
-        // No-op
-    }
-
-    @Override
-    public void onDataTreeChanged(final Collection<DataTreeCandidate> changes) {
-        for (DataTreeCandidate change : changes) {
-            DataTreeCandidateNode changeRoot = change.getRootNode();
-            LeafNode<?> ownerLeaf = (LeafNode<?>) changeRoot.getDataAfter().get();
-            String entityType = entityTypeFromEntityPath(change.getRootPath());
-            String newOwner = extractOwner(ownerLeaf);
-            if (!Strings.isNullOrEmpty(newOwner)) {
-                updateStatistics(entityType, newOwner, 1);
-            }
-
-            Optional<NormalizedNode> dataBefore = changeRoot.getDataBefore();
-            if (dataBefore.isPresent()) {
-                String origOwner = extractOwner((LeafNode<?>) changeRoot.getDataBefore().get());
-                if (!Strings.isNullOrEmpty(origOwner)) {
-                    updateStatistics(entityType, origOwner, -1);
-                }
-            }
-        }
-    }
-
-    Map<String, Map<String, Long>> all() {
-        Map<String, Map<String, Long>> snapshot = new HashMap<>();
-        for (String entityType : statistics.immutableSnapshot().keySet()) {
-            snapshot.put(entityType, byEntityType(entityType));
-        }
-        return snapshot;
-    }
-
-    Map<String, Long> byEntityType(final String entityType) {
-        if (statistics.get(entityType) != null) {
-            return statistics.get(entityType).immutableSnapshot();
-        }
-        return new HashMap<>();
-    }
-
-    private void updateStatistics(final String entityType, final String candidateName, final long count) {
-        TrieMap<String, Long> map = statistics.get(entityType);
-        if (map == null) {
-            map = TrieMap.create();
-            map.put(candidateName, count);
-            statistics.put(entityType, map);
-        } else {
-            map.merge(candidateName, count, (ownedEntities, addedEntities) -> ownedEntities + addedEntities);
-        }
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/OSGiDistributedEntityOwnershipService.java b/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/OSGiDistributedEntityOwnershipService.java
deleted file mode 100644 (file)
index cceae6c..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2020 PANTHEON.tech, s.r.o. 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.entityownership;
-
-import com.google.common.annotations.Beta;
-import java.util.Map;
-import java.util.Optional;
-import org.opendaylight.controller.cluster.datastore.DistributedDataStoreInterface;
-import org.opendaylight.controller.cluster.entityownership.selectionstrategy.EntityOwnerSelectionStrategyConfigReader;
-import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException;
-import org.opendaylight.mdsal.eos.common.api.EntityOwnershipState;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntity;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipCandidateRegistration;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipListener;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipListenerRegistration;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipService;
-import org.osgi.service.component.annotations.Activate;
-import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Deactivate;
-import org.osgi.service.component.annotations.Reference;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Beta
-@Component(immediate = true, configurationPid = "org.opendaylight.controller.cluster.entity.owner.selection.strategies",
-    property = "type=default")
-public final class OSGiDistributedEntityOwnershipService implements DOMEntityOwnershipService {
-    private static final Logger LOG = LoggerFactory.getLogger(OSGiDistributedEntityOwnershipService.class);
-
-    @Reference(target = "(type=distributed-operational)")
-    DistributedDataStoreInterface operDatastore = null;
-
-    private DistributedEntityOwnershipService delegate;
-
-    @Override
-    public DOMEntityOwnershipCandidateRegistration registerCandidate(final DOMEntity entity)
-            throws CandidateAlreadyRegisteredException {
-        return delegate.registerCandidate(entity);
-    }
-
-    @Override
-    public DOMEntityOwnershipListenerRegistration registerListener(final String entityType,
-            final DOMEntityOwnershipListener listener) {
-        return delegate.registerListener(entityType, listener);
-    }
-
-    @Override
-    public Optional<EntityOwnershipState> getOwnershipState(final DOMEntity forEntity) {
-        return delegate.getOwnershipState(forEntity);
-    }
-
-    @Override
-    public boolean isCandidateRegistered(final DOMEntity forEntity) {
-        return delegate.isCandidateRegistered(forEntity);
-    }
-
-    @Activate
-    // FIXME: 3.0.0: properties are keyed by String, this should be Map<String, Object>
-    void activate(final Map<Object, Object> properties) {
-        LOG.info("Distributed Entity Ownership Service starting");
-        delegate = DistributedEntityOwnershipService.start(operDatastore.getActorUtils(),
-            EntityOwnerSelectionStrategyConfigReader.loadStrategyWithConfig(properties));
-        LOG.info("Distributed Entity Ownership Service started");
-    }
-
-    @Deactivate
-    void deactivate() {
-        LOG.info("Distributed Entity Ownership Service stopping");
-        delegate.close();
-        LOG.info("Distributed Entity Ownership Service stopped");
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/messages/CandidateAdded.java b/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/messages/CandidateAdded.java
deleted file mode 100644 (file)
index 2fb6bda..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco 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.entityownership.messages;
-
-import java.util.Collection;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-
-/**
- * Message sent when a new candidate is added for an entity.
- *
- * @author Moiz Raja
- * @author Thomas Pantelis
- */
-public class CandidateAdded {
-    private final YangInstanceIdentifier entityPath;
-    private final Collection<String> allCandidates;
-    private final String newCandidate;
-
-    public CandidateAdded(final YangInstanceIdentifier entityPath, final String newCandidate,
-            final Collection<String> allCandidates) {
-        this.entityPath = entityPath;
-        this.newCandidate = newCandidate;
-        this.allCandidates = allCandidates;
-    }
-
-    public YangInstanceIdentifier getEntityPath() {
-        return entityPath;
-    }
-
-    public Collection<String> getAllCandidates() {
-        return allCandidates;
-    }
-
-    public String getNewCandidate() {
-        return newCandidate;
-    }
-
-    @Override
-    public String toString() {
-        return "CandidateAdded [entityPath=" + entityPath + ", newCandidate=" + newCandidate + ", allCandidates="
-                + allCandidates + "]";
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/messages/CandidateRemoved.java b/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/messages/CandidateRemoved.java
deleted file mode 100644 (file)
index d3e659c..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco 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.entityownership.messages;
-
-import java.util.Collection;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-
-/**
- * Message sent when a candidate is removed for an entity.
- *
- * @author Moiz Raja
- * @author Thomas Pantelis
- */
-public class CandidateRemoved {
-    private final YangInstanceIdentifier entityPath;
-    private final String removedCandidate;
-    private final Collection<String> remainingCandidates;
-
-    public CandidateRemoved(final YangInstanceIdentifier entityPath, final String removedCandidate,
-            final Collection<String> remainingCandidates) {
-        this.entityPath = entityPath;
-        this.removedCandidate = removedCandidate;
-        this.remainingCandidates = remainingCandidates;
-    }
-
-    public YangInstanceIdentifier getEntityPath() {
-        return entityPath;
-    }
-
-    public String getRemovedCandidate() {
-        return removedCandidate;
-    }
-
-    public Collection<String> getRemainingCandidates() {
-        return remainingCandidates;
-    }
-
-    @Override
-    public String toString() {
-        return "CandidateRemoved [entityPath=" + entityPath + ", removedCandidate=" + removedCandidate
-                + ", remainingCandidates=" + remainingCandidates + "]";
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/messages/RegisterCandidateLocal.java b/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/messages/RegisterCandidateLocal.java
deleted file mode 100644 (file)
index 3e70d2b..0000000
+++ /dev/null
@@ -1,32 +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.entityownership.messages;
-
-import org.opendaylight.mdsal.eos.dom.api.DOMEntity;
-
-/**
- * Message sent to the local EntityOwnershipShard to register a candidate.
- *
- * @author Thomas Pantelis
- */
-public class RegisterCandidateLocal {
-    private final DOMEntity entity;
-
-    public RegisterCandidateLocal(final DOMEntity entity) {
-        this.entity = entity;
-    }
-
-    public DOMEntity getEntity() {
-        return entity;
-    }
-
-    @Override
-    public String toString() {
-        return "RegisterCandidateLocal [entity=" + entity + "]";
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/messages/RegisterListenerLocal.java b/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/messages/RegisterListenerLocal.java
deleted file mode 100644 (file)
index 2c9ebab..0000000
+++ /dev/null
@@ -1,42 +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.entityownership.messages;
-
-import static java.util.Objects.requireNonNull;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipListener;
-
-/**
- * Message sent to the local EntityOwnershipShard to register an EntityOwnershipListener.
- *
- * @author Thomas Pantelis
- */
-@NonNullByDefault
-public class RegisterListenerLocal {
-    private final DOMEntityOwnershipListener listener;
-    private final String entityType;
-
-    public RegisterListenerLocal(final DOMEntityOwnershipListener listener, final String entityType) {
-        this.listener = requireNonNull(listener, "listener cannot be null");
-        this.entityType = requireNonNull(entityType, "entityType cannot be null");
-    }
-
-    public DOMEntityOwnershipListener getListener() {
-        return listener;
-    }
-
-    public String getEntityType() {
-        return entityType;
-    }
-
-    @Override
-    public String toString() {
-        return "RegisterListenerLocal [entityType=" + entityType + ", listener=" + listener + "]";
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/messages/RemoveAllCandidates.java b/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/messages/RemoveAllCandidates.java
deleted file mode 100644 (file)
index 843a3dc..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2016 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.entityownership.messages;
-
-import java.io.Serializable;
-import org.opendaylight.controller.cluster.access.concepts.MemberName;
-
-/**
- * Message sent by an EntityOwnershipShard to its leader on startup to remove all its candidates.
- *
- * @author Thomas Pantelis
- */
-public class RemoveAllCandidates implements Serializable {
-    private static final long serialVersionUID = 1L;
-
-    private final MemberName memberName;
-
-    public RemoveAllCandidates(final MemberName memberName) {
-        this.memberName = memberName;
-    }
-
-    public MemberName getMemberName() {
-        return memberName;
-    }
-
-    @Override
-    public String toString() {
-        return "RemoveAllCandidates [memberName=" + memberName + "]";
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/messages/SelectOwner.java b/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/messages/SelectOwner.java
deleted file mode 100644 (file)
index e7307bf..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco 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.entityownership.messages;
-
-import static java.util.Objects.requireNonNull;
-
-import java.util.Collection;
-import org.opendaylight.controller.cluster.entityownership.selectionstrategy.EntityOwnerSelectionStrategy;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-
-/**
- * Message sent when a new owner needs to be selected.
- */
-public class SelectOwner {
-    private final YangInstanceIdentifier entityPath;
-    private final Collection<String> allCandidates;
-    private final EntityOwnerSelectionStrategy ownerSelectionStrategy;
-
-    public SelectOwner(final YangInstanceIdentifier entityPath, final Collection<String> allCandidates,
-                       final EntityOwnerSelectionStrategy ownerSelectionStrategy) {
-        this.entityPath = requireNonNull(entityPath, "entityPath should not be null");
-        this.allCandidates = requireNonNull(allCandidates, "allCandidates should not be null");
-        this.ownerSelectionStrategy = requireNonNull(ownerSelectionStrategy,
-            "ownerSelectionStrategy should not be null");
-    }
-
-    public YangInstanceIdentifier getEntityPath() {
-        return entityPath;
-    }
-
-    public Collection<String> getAllCandidates() {
-        return allCandidates;
-    }
-
-    public EntityOwnerSelectionStrategy getOwnerSelectionStrategy() {
-        return ownerSelectionStrategy;
-    }
-
-    @Override
-    public String toString() {
-        return "SelectOwner [entityPath=" + entityPath + ", allCandidates=" + allCandidates
-                + ", ownerSelectionStrategy=" + ownerSelectionStrategy + "]";
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/messages/UnregisterCandidateLocal.java b/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/messages/UnregisterCandidateLocal.java
deleted file mode 100644 (file)
index 7c4cabb..0000000
+++ /dev/null
@@ -1,32 +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.entityownership.messages;
-
-import org.opendaylight.mdsal.eos.dom.api.DOMEntity;
-
-/**
- * Message sent to the local EntityOwnershipShard to unregister a candidate.
- *
- * @author Thomas Pantelis
- */
-public class UnregisterCandidateLocal {
-    private final DOMEntity entity;
-
-    public UnregisterCandidateLocal(final DOMEntity entity) {
-        this.entity = entity;
-    }
-
-    public DOMEntity getEntity() {
-        return entity;
-    }
-
-    @Override
-    public String toString() {
-        return "UnregisterCandidateLocal [entity=" + entity + "]";
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/messages/UnregisterListenerLocal.java b/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/messages/UnregisterListenerLocal.java
deleted file mode 100644 (file)
index 1652c33..0000000
+++ /dev/null
@@ -1,38 +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.entityownership.messages;
-
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipListener;
-
-/**
- * Message sent to the local EntityOwnershipShard to unregister an EntityOwnershipListener.
- *
- * @author Thomas Pantelis
- */
-public class UnregisterListenerLocal {
-    private final DOMEntityOwnershipListener listener;
-    private final String entityType;
-
-    public UnregisterListenerLocal(final DOMEntityOwnershipListener listener, final String entityType) {
-        this.listener = listener;
-        this.entityType = entityType;
-    }
-
-    public DOMEntityOwnershipListener getListener() {
-        return listener;
-    }
-
-    public String getEntityType() {
-        return entityType;
-    }
-
-    @Override
-    public String toString() {
-        return "UnregisterListenerLocal [entityType=" + entityType + ", listener=" + listener + "]";
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/selectionstrategy/AbstractEntityOwnerSelectionStrategy.java b/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/selectionstrategy/AbstractEntityOwnerSelectionStrategy.java
deleted file mode 100644 (file)
index 23cd5be..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco 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.entityownership.selectionstrategy;
-
-import java.util.Map;
-
-public abstract class AbstractEntityOwnerSelectionStrategy implements EntityOwnerSelectionStrategy {
-
-    private final long selectionDelayInMillis;
-    private final Map<String, Long> initialStatistics;
-
-    protected AbstractEntityOwnerSelectionStrategy(final long selectionDelayInMillis,
-            final Map<String, Long> initialStatistics) {
-        this.selectionDelayInMillis = selectionDelayInMillis;
-        this.initialStatistics = initialStatistics;
-    }
-
-    @Override
-    public long getSelectionDelayInMillis() {
-        return selectionDelayInMillis;
-    }
-
-    public Map<String, Long> getInitialStatistics() {
-        return initialStatistics;
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/selectionstrategy/EntityOwnerSelectionStrategy.java b/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/selectionstrategy/EntityOwnerSelectionStrategy.java
deleted file mode 100644 (file)
index df19a65..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco 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.entityownership.selectionstrategy;
-
-import java.util.Collection;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * An EntityOwnerSelectionStrategy is to be used by the EntityOwnershipShard to select a new owner from a collection
- * of candidates.
- */
-public interface EntityOwnerSelectionStrategy {
-    /**
-     * Returns the time in millis owner selection should be delayed.
-     *
-     * @return the time in millis owner selection should be delayed
-     */
-    long getSelectionDelayInMillis();
-
-    /**
-     * Selects a new owner from the list of viable candidates.
-     *
-     * @param currentOwner the current owner of the entity if any, null otherwise
-     * @param viableCandidates the available candidates from which to choose the new owner
-     * @return the new owner
-     */
-    String newOwner(@Nullable String currentOwner, Collection<String> viableCandidates);
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/selectionstrategy/EntityOwnerSelectionStrategyConfig.java b/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/selectionstrategy/EntityOwnerSelectionStrategyConfig.java
deleted file mode 100644 (file)
index fb6b278..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco 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.entityownership.selectionstrategy;
-
-import java.lang.reflect.InvocationTargetException;
-import java.util.HashMap;
-import java.util.Map;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * FIXME: this is simple registry service, except it also loads classes.
- */
-public final class EntityOwnerSelectionStrategyConfig {
-    private static final Logger LOG = LoggerFactory.getLogger(EntityOwnerSelectionStrategyConfig.class);
-    private final Map<String, StrategyInfo> entityTypeToStrategyInfo = new HashMap<>();
-    private final Map<String, EntityOwnerSelectionStrategy> entityTypeToOwnerSelectionStrategy = new HashMap<>();
-
-    private EntityOwnerSelectionStrategyConfig() {
-
-    }
-
-    public boolean isStrategyConfigured(final String entityType) {
-        return entityTypeToStrategyInfo.get(entityType) != null;
-    }
-
-    public EntityOwnerSelectionStrategy createStrategy(final String entityType,
-            final Map<String, Long> initialStatistics) {
-        final EntityOwnerSelectionStrategy strategy;
-        final EntityOwnerSelectionStrategy existingStrategy = entityTypeToOwnerSelectionStrategy.get(entityType);
-        if (existingStrategy != null) {
-            strategy = existingStrategy;
-        } else {
-            EntityOwnerSelectionStrategyConfig.StrategyInfo strategyInfo = entityTypeToStrategyInfo.get(entityType);
-            if (strategyInfo == null) {
-                strategy = FirstCandidateSelectionStrategy.INSTANCE;
-            } else {
-                strategy = strategyInfo.createStrategy(initialStatistics);
-            }
-            entityTypeToOwnerSelectionStrategy.put(entityType, strategy);
-        }
-        return strategy;
-    }
-
-    /**
-     * This class should not exist. It contains a single long, which is passed to the constructor (via reflection).
-     * We are getting that information from a BundleContext. We are running in OSGi environment, hence this class
-     * needs to be deployed in its own bundle, with its own configuration.
-     * If this is used internally, it needs to be relocated into a separate package along with the implementation
-     * using it.
-     *
-     * @deprecated FIXME: THIS IS CONFIGURATION FOR A CUSTOM-LOADED CLASS CONSTRUCTOR
-     */
-    @Deprecated
-    public void clearStrategies() {
-        entityTypeToOwnerSelectionStrategy.clear();
-    }
-
-    private static final class StrategyInfo {
-        private final Class<? extends EntityOwnerSelectionStrategy> strategyClass;
-        private final long delay;
-
-        private StrategyInfo(final Class<? extends EntityOwnerSelectionStrategy> strategyClass, final long delay) {
-            this.strategyClass = strategyClass;
-            this.delay = delay;
-        }
-
-        public EntityOwnerSelectionStrategy createStrategy(final Map<String, Long> initialStatistics) {
-            try {
-                return strategyClass.getDeclaredConstructor(long.class, Map.class)
-                        .newInstance(delay, initialStatistics);
-            } catch (InstantiationException | IllegalAccessException | InvocationTargetException
-                    | NoSuchMethodException e) {
-                LOG.warn("could not create custom strategy", e);
-            }
-            return FirstCandidateSelectionStrategy.INSTANCE;
-        }
-    }
-
-    public static Builder newBuilder() {
-        return new Builder(new EntityOwnerSelectionStrategyConfig());
-    }
-
-    public static final class Builder {
-        private final EntityOwnerSelectionStrategyConfig config;
-
-        Builder(final EntityOwnerSelectionStrategyConfig config) {
-            this.config = config;
-        }
-
-        public Builder addStrategy(final String entityType,
-                final Class<? extends EntityOwnerSelectionStrategy> strategy, final long delay) {
-            config.entityTypeToStrategyInfo.put(entityType, new StrategyInfo(strategy, delay));
-            return this;
-        }
-
-        public EntityOwnerSelectionStrategyConfig build() {
-            return this.config;
-        }
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/selectionstrategy/EntityOwnerSelectionStrategyConfigReader.java b/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/selectionstrategy/EntityOwnerSelectionStrategyConfigReader.java
deleted file mode 100644 (file)
index 8bac3dd..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco 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.entityownership.selectionstrategy;
-
-import com.google.common.base.Preconditions;
-import java.util.Map;
-import java.util.Map.Entry;
-import org.opendaylight.controller.cluster.entityownership.selectionstrategy.EntityOwnerSelectionStrategyConfig.Builder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Reads the entity owner selection strategy config.
- *
- */
-public final class EntityOwnerSelectionStrategyConfigReader {
-
-    private static final Logger LOG = LoggerFactory.getLogger(EntityOwnerSelectionStrategyConfigReader.class);
-    private static final String ENTITY_TYPE_PREFIX = "entity.type.";
-
-    private EntityOwnerSelectionStrategyConfigReader() {
-        // Hidden on purpose
-    }
-
-    @SuppressWarnings("checkstyle:IllegalCatch")
-    public static EntityOwnerSelectionStrategyConfig loadStrategyWithConfig(final Map<Object, Object> props) {
-        final EntityOwnerSelectionStrategyConfig.Builder builder = EntityOwnerSelectionStrategyConfig.newBuilder();
-
-        if (props != null && !props.isEmpty()) {
-            parseConfiguration(builder, props);
-        } else {
-            if (props == null) {
-                LOG.debug("Could not read strategy configuration file, will use default configuration.");
-            } else {
-                LOG.debug("Configuration file is empty, will use default configuration.");
-            }
-        }
-        return builder.build();
-    }
-
-    private static EntityOwnerSelectionStrategyConfig parseConfiguration(final Builder builder,
-            final Map<Object, Object> properties) {
-
-        for (final Entry<Object, Object> entry : properties.entrySet()) {
-            final String key = (String) entry.getKey();
-            if (!key.startsWith(ENTITY_TYPE_PREFIX)) {
-                LOG.debug("Ignoring non-conforming property key : {}", key);
-                continue;
-            }
-
-            final String[] strategyClassAndDelay = ((String) properties.get(key)).split(",");
-            final Class<? extends EntityOwnerSelectionStrategy> aClass = loadClass(strategyClassAndDelay[0]);
-
-            final long delay;
-            if (strategyClassAndDelay.length > 1) {
-                delay = Long.parseLong(strategyClassAndDelay[1]);
-            } else {
-                delay = 0;
-            }
-
-            final String entityType = key.substring(key.lastIndexOf(".") + 1);
-            builder.addStrategy(entityType, aClass, delay);
-            LOG.debug("Entity Type '{}' using strategy {} delay {}", entityType, aClass, delay);
-        }
-
-        return builder.build();
-    }
-
-    @SuppressWarnings("unchecked")
-    private static Class<? extends EntityOwnerSelectionStrategy> loadClass(final String strategyClassAndDelay) {
-        final Class<?> clazz;
-        try {
-            clazz = EntityOwnerSelectionStrategyConfigReader.class.getClassLoader().loadClass(strategyClassAndDelay);
-        } catch (final ClassNotFoundException e) {
-            throw new IllegalArgumentException("Failed to load strategy " + strategyClassAndDelay, e);
-        }
-
-        Preconditions.checkArgument(EntityOwnerSelectionStrategy.class.isAssignableFrom(clazz),
-            "Selected implementation %s must implement EntityOwnerSelectionStrategy, clazz");
-
-        return (Class<? extends EntityOwnerSelectionStrategy>) clazz;
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/selectionstrategy/FirstCandidateSelectionStrategy.java b/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/selectionstrategy/FirstCandidateSelectionStrategy.java
deleted file mode 100644 (file)
index 9a18f72..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco 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.entityownership.selectionstrategy;
-
-import com.google.common.base.Preconditions;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
-
-/**
- * The FirstCandidateSelectionStrategy always selects the first viable candidate from the list of candidates.
- */
-public class FirstCandidateSelectionStrategy extends AbstractEntityOwnerSelectionStrategy {
-
-    public static final FirstCandidateSelectionStrategy INSTANCE =
-            new FirstCandidateSelectionStrategy(0L, Collections.emptyMap());
-
-    public FirstCandidateSelectionStrategy(final long selectionDelayInMillis,
-            final Map<String, Long> initialStatistics) {
-        super(selectionDelayInMillis, initialStatistics);
-    }
-
-    @Override
-    public String newOwner(final String currentOwner, final Collection<String> viableCandidates) {
-        Preconditions.checkArgument(viableCandidates.size() > 0, "No viable candidates provided");
-        return viableCandidates.iterator().next();
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/selectionstrategy/LeastLoadedCandidateSelectionStrategy.java b/opendaylight/md-sal/sal-distributed-eos/src/main/java/org/opendaylight/controller/cluster/entityownership/selectionstrategy/LeastLoadedCandidateSelectionStrategy.java
deleted file mode 100644 (file)
index fc53f95..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco 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.entityownership.selectionstrategy;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static java.util.Objects.requireNonNullElse;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Strings;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * The LeastLoadedCandidateSelectionStrategy assigns ownership for an entity to the candidate which owns the least
- * number of entities.
- */
-public class LeastLoadedCandidateSelectionStrategy extends AbstractEntityOwnerSelectionStrategy {
-    private final Map<String, Long> localStatistics = new HashMap<>();
-
-    protected LeastLoadedCandidateSelectionStrategy(final long selectionDelayInMillis,
-            final Map<String, Long> initialStatistics) {
-        super(selectionDelayInMillis, initialStatistics);
-
-        localStatistics.putAll(initialStatistics);
-    }
-
-    @Override
-    public String newOwner(final String currentOwner, final Collection<String> viableCandidates) {
-        checkArgument(viableCandidates.size() > 0);
-        String leastLoadedCandidate = null;
-        long leastLoadedCount = Long.MAX_VALUE;
-
-        if (!Strings.isNullOrEmpty(currentOwner)) {
-            long localVal = requireNonNullElse(localStatistics.get(currentOwner), 0L);
-            localStatistics.put(currentOwner, localVal - 1);
-        }
-
-        for (String candidateName : viableCandidates) {
-            long val = requireNonNullElse(localStatistics.get(candidateName), 0L);
-            if (val < leastLoadedCount) {
-                leastLoadedCount = val;
-                leastLoadedCandidate = candidateName;
-            }
-        }
-
-        if (leastLoadedCandidate == null) {
-            leastLoadedCandidate = viableCandidates.iterator().next();
-        }
-
-        localStatistics.put(leastLoadedCandidate, leastLoadedCount + 1);
-        return leastLoadedCandidate;
-    }
-
-    @VisibleForTesting
-    Map<String, Long> getLocalStatistics() {
-        return localStatistics;
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/main/yang/entity-owners.yang b/opendaylight/md-sal/sal-distributed-eos/src/main/yang/entity-owners.yang
deleted file mode 100644 (file)
index 0f37e13..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-module entity-owners {
-    yang-version 1;
-    namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:clustering:entity-owners";
-    prefix "entity-owners";
-
-    description
-        "This module contains the base YANG definitions for
-        an implementation of the EntityOwnershipService which stores
-        entity ownership information in the data store";
-
-    revision "2015-08-04" {
-        description "Initial revision.";
-    }
-
-    container entity-owners {
-
-        // A list of all entities grouped by type
-        list entity-type {
-            key type;
-            leaf type {
-                type string;
-            }
-
-            list entity {
-                key id;
-
-                leaf id {
-                    type instance-identifier;
-                }
-
-                leaf owner {
-                    type string;
-                }
-
-                // A list of all the candidates that would like to own the entity
-                list candidate {
-                    key name;
-                    ordered-by user;
-
-                    leaf name {
-                        type string;
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/AbstractClusterRefEntityOwnershipTest.java b/opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/AbstractClusterRefEntityOwnershipTest.java
deleted file mode 100644 (file)
index 6d127c3..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco 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.entityownership;
-
-import akka.actor.ActorSystem;
-import akka.testkit.javadsl.TestKit;
-import com.typesafe.config.ConfigFactory;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-
-public class AbstractClusterRefEntityOwnershipTest extends AbstractEntityOwnershipTest {
-
-    private static ActorSystem system;
-
-    @BeforeClass
-    public static void setUpClass() {
-        system = ActorSystem.create("test", ConfigFactory.load().getConfig("test-config"));
-    }
-
-    @AfterClass
-    public static void tearDownClass() {
-        TestKit.shutdownActorSystem(system);
-        system = null;
-    }
-
-    protected static ActorSystem getSystem() {
-        return system;
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/AbstractEntityOwnershipTest.java b/opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/AbstractEntityOwnershipTest.java
deleted file mode 100644 (file)
index 7fbe4d5..0000000
+++ /dev/null
@@ -1,307 +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.entityownership;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.CANDIDATE_NAME_QNAME;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.ENTITY_ID_QNAME;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.ENTITY_OWNERS_PATH;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.ENTITY_OWNER_QNAME;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.ENTITY_QNAME;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.ENTITY_TYPE_QNAME;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.candidatePath;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.entityPath;
-
-import akka.pattern.Patterns;
-import akka.testkit.TestActorRef;
-import akka.util.Timeout;
-import com.google.common.base.Stopwatch;
-import com.google.common.util.concurrent.Uninterruptibles;
-import java.util.Optional;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.function.Consumer;
-import java.util.function.Function;
-import org.opendaylight.controller.cluster.access.concepts.MemberName;
-import org.opendaylight.controller.cluster.datastore.AbstractActorTest;
-import org.opendaylight.controller.cluster.datastore.AbstractShardTest;
-import org.opendaylight.controller.cluster.datastore.ShardDataTree;
-import org.opendaylight.controller.cluster.datastore.identifiers.ShardIdentifier;
-import org.opendaylight.controller.cluster.raft.client.messages.GetOnDemandRaftState;
-import org.opendaylight.controller.cluster.raft.client.messages.OnDemandRaftState;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntity;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipChange;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.clustering.entity.owners.rev150804.EntityOwners;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.clustering.entity.owners.rev150804.entity.owners.EntityType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.clustering.entity.owners.rev150804.entity.owners.entity.type.entity.Candidate;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import scala.concurrent.Await;
-import scala.concurrent.Future;
-import scala.concurrent.duration.FiniteDuration;
-
-/**
- * Abstract base class providing utility methods.
- *
- * @author Thomas Pantelis
- */
-public class AbstractEntityOwnershipTest extends AbstractActorTest {
-    protected final Logger testLog = LoggerFactory.getLogger(getClass());
-
-    private static final AtomicInteger NEXT_SHARD_NUM = new AtomicInteger();
-
-    protected void verifyEntityCandidate(final NormalizedNode node, final String entityType,
-            final YangInstanceIdentifier entityId, final String candidateName, final boolean expectPresent) {
-        try {
-            assertNotNull("Missing " + EntityOwners.QNAME.toString(), node);
-            assertTrue(node instanceof ContainerNode);
-
-            ContainerNode entityOwnersNode = (ContainerNode) node;
-
-            MapEntryNode entityTypeEntry = getMapEntryNodeChild(entityOwnersNode, EntityType.QNAME,
-                    ENTITY_TYPE_QNAME, entityType, true);
-
-            MapEntryNode entityEntry = getMapEntryNodeChild(entityTypeEntry, ENTITY_QNAME, ENTITY_ID_QNAME,
-                    entityId, true);
-
-            getMapEntryNodeChild(entityEntry, Candidate.QNAME, CANDIDATE_NAME_QNAME, candidateName, expectPresent);
-        } catch (AssertionError e) {
-            throw new AssertionError("Verification of entity candidate failed - returned data was: " + node, e);
-        }
-    }
-
-    protected void verifyEntityCandidate(final String entityType, final YangInstanceIdentifier entityId,
-            final String candidateName, final Function<YangInstanceIdentifier,NormalizedNode> reader,
-            final boolean expectPresent) {
-        AssertionError lastError = null;
-        Stopwatch sw = Stopwatch.createStarted();
-        while (sw.elapsed(TimeUnit.MILLISECONDS) <= 5000) {
-            NormalizedNode node = reader.apply(ENTITY_OWNERS_PATH);
-            try {
-                verifyEntityCandidate(node, entityType, entityId, candidateName, expectPresent);
-                return;
-            } catch (AssertionError e) {
-                lastError = e;
-                Uninterruptibles.sleepUninterruptibly(100, TimeUnit.MILLISECONDS);
-            }
-        }
-
-        throw lastError;
-    }
-
-    protected void verifyEntityCandidate(final String entityType, final YangInstanceIdentifier entityId,
-            final String candidateName, final Function<YangInstanceIdentifier,NormalizedNode> reader) {
-        verifyEntityCandidate(entityType, entityId, candidateName, reader, true);
-    }
-
-    protected MapEntryNode getMapEntryNodeChild(final DataContainerNode parent,
-            final QName childMap, final QName child, final Object key, final boolean expectPresent) {
-        Optional<DataContainerChild> childNode = parent.findChildByArg(new NodeIdentifier(childMap));
-        // We have to account for empty maps disappearing. If we expect the entry to be non-present, tolerate a missing
-        // map.
-        if (!expectPresent && !childNode.isPresent()) {
-            return null;
-        }
-
-        assertTrue("Missing " + childMap.toString(), childNode.isPresent());
-
-        MapNode entityTypeMapNode = (MapNode) childNode.get();
-        Optional<MapEntryNode> entityTypeEntry = entityTypeMapNode.findChildByArg(NodeIdentifierWithPredicates.of(
-                childMap, child, key));
-        if (expectPresent && !entityTypeEntry.isPresent()) {
-            fail("Missing " + childMap.toString() + " entry for " + key + ". Actual: " + entityTypeMapNode.body());
-        } else if (!expectPresent && entityTypeEntry.isPresent()) {
-            fail("Found unexpected " + childMap.toString() + " entry for " + key);
-        }
-
-        return entityTypeEntry.isPresent() ? entityTypeEntry.get() : null;
-    }
-
-    static void verifyOwner(final String expected, final String entityType, final YangInstanceIdentifier entityId,
-            final Function<YangInstanceIdentifier,NormalizedNode> reader) {
-        AssertionError lastError = null;
-        YangInstanceIdentifier entityPath = entityPath(entityType, entityId).node(ENTITY_OWNER_QNAME);
-        Stopwatch sw = Stopwatch.createStarted();
-        while (sw.elapsed(TimeUnit.MILLISECONDS) <= 5000) {
-            try {
-                NormalizedNode node = reader.apply(entityPath);
-                assertNotNull("Owner was not set for entityId: " + entityId, node);
-                assertEquals("Entity owner", expected, node.body().toString());
-                return;
-            } catch (AssertionError e) {
-                lastError = e;
-                Uninterruptibles.sleepUninterruptibly(100, TimeUnit.MILLISECONDS);
-            }
-        }
-
-        throw lastError;
-    }
-
-    @SuppressWarnings("checkstyle:IllegalCatch")
-    static void verifyOwner(final TestActorRef<? extends EntityOwnershipShard> shard, final String entityType,
-            final YangInstanceIdentifier entityId, final String localMemberName) {
-        verifyOwner(localMemberName, entityType, entityId, path -> {
-            try {
-                return AbstractShardTest.readStore(shard, path);
-            } catch (Exception e) {
-                return null;
-            }
-        });
-    }
-
-    protected void verifyNodeRemoved(final YangInstanceIdentifier path,
-            final Function<YangInstanceIdentifier,NormalizedNode> reader) {
-        AssertionError lastError = null;
-        Stopwatch sw = Stopwatch.createStarted();
-        while (sw.elapsed(TimeUnit.MILLISECONDS) <= 5000) {
-            try {
-                assertNull("Node was not removed at path: " + path, reader.apply(path));
-                return;
-            } catch (AssertionError e) {
-                lastError = e;
-                Uninterruptibles.sleepUninterruptibly(100, TimeUnit.MILLISECONDS);
-            }
-        }
-
-        throw lastError;
-    }
-
-    static void writeNode(final YangInstanceIdentifier path, final NormalizedNode node,
-            final ShardDataTree shardDataTree) throws DataValidationFailedException {
-        DataTreeModification modification = shardDataTree.newModification();
-        modification.merge(path, node);
-        commit(shardDataTree, modification);
-    }
-
-    static void deleteNode(final YangInstanceIdentifier path, final ShardDataTree shardDataTree)
-            throws DataValidationFailedException {
-        DataTreeModification modification = shardDataTree.newModification();
-        modification.delete(path);
-        commit(shardDataTree, modification);
-    }
-
-    static void commit(final ShardDataTree shardDataTree, final DataTreeModification modification)
-            throws DataValidationFailedException {
-        modification.ready();
-        shardDataTree.getDataTree().validate(modification);
-        final DataTreeCandidate candidate = shardDataTree.getDataTree().prepare(modification);
-        shardDataTree.getDataTree().commit(candidate);
-        shardDataTree.notifyListeners(candidate);
-    }
-
-    static DOMEntityOwnershipChange ownershipChange(final DOMEntity expEntity, final boolean expWasOwner,
-            final boolean expIsOwner, final boolean expHasOwner) {
-        return ownershipChange(expEntity, expWasOwner, expIsOwner, expHasOwner, false);
-    }
-
-    static DOMEntityOwnershipChange ownershipChange(final DOMEntity expEntity, final boolean expWasOwner,
-            final boolean expIsOwner, final boolean expHasOwner, final boolean expInJeopardy) {
-        return argThat(change -> expEntity.equals(change.getEntity()) && expWasOwner == change.getState().wasOwner()
-                && expIsOwner == change.getState().isOwner() && expHasOwner == change.getState().hasOwner()
-                && expInJeopardy == change.inJeopardy());
-    }
-
-    static DOMEntityOwnershipChange ownershipChange(final DOMEntity expEntity) {
-        return argThat(change -> expEntity.equals(change.getEntity()));
-    }
-
-    @SuppressWarnings("checkstyle:IllegalCatch")
-    static void verifyNoOwnerSet(final TestActorRef<? extends EntityOwnershipShard> shard, final String entityType,
-            final YangInstanceIdentifier entityId) {
-        YangInstanceIdentifier entityPath = entityPath(entityType, entityId).node(ENTITY_OWNER_QNAME);
-        try {
-            NormalizedNode node = AbstractShardTest.readStore(shard, entityPath);
-            if (node != null) {
-                fail("Owner " + node.body() + " was set for " + entityPath);
-            }
-
-        } catch (Exception e) {
-            throw new AssertionError("read failed", e);
-        }
-    }
-
-    static void verifyRaftState(final TestActorRef<? extends EntityOwnershipShard> shard,
-            final Consumer<OnDemandRaftState> verifier)
-            throws Exception {
-        AssertionError lastError = null;
-        Stopwatch sw = Stopwatch.createStarted();
-        while (sw.elapsed(TimeUnit.SECONDS) <= 5) {
-            FiniteDuration operationDuration = FiniteDuration.create(5, TimeUnit.SECONDS);
-            Future<Object> future = Patterns.ask(shard, GetOnDemandRaftState.INSTANCE, new Timeout(operationDuration));
-            OnDemandRaftState raftState = (OnDemandRaftState)Await.result(future, operationDuration);
-            try {
-                verifier.accept(raftState);
-                return;
-            } catch (AssertionError e) {
-                lastError = e;
-                Uninterruptibles.sleepUninterruptibly(50, TimeUnit.MILLISECONDS);
-            }
-        }
-
-        throw lastError;
-    }
-
-    static ShardIdentifier newShardId(final String memberName) {
-        return ShardIdentifier.create("entity-ownership", MemberName.forName(memberName),
-            "operational" + NEXT_SHARD_NUM.getAndIncrement());
-    }
-
-    @SuppressWarnings("checkstyle:IllegalCatch")
-    void verifyEntityCandidateRemoved(final TestActorRef<EntityOwnershipShard> shard, final String entityType,
-            final YangInstanceIdentifier entityId, final String candidateName) {
-        verifyNodeRemoved(candidatePath(entityType, entityId, candidateName), path -> {
-            try {
-                return AbstractShardTest.readStore(shard, path);
-            } catch (Exception e) {
-                throw new AssertionError("Failed to read " + path, e);
-            }
-        });
-    }
-
-    @SuppressWarnings("checkstyle:IllegalCatch")
-    void verifyCommittedEntityCandidate(final TestActorRef<? extends EntityOwnershipShard> shard,
-            final String entityType, final YangInstanceIdentifier entityId, final String candidateName) {
-        verifyEntityCandidate(entityType, entityId, candidateName, path -> {
-            try {
-                return AbstractShardTest.readStore(shard, path);
-            } catch (Exception e) {
-                throw new AssertionError("Failed to read " + path, e);
-            }
-        });
-    }
-
-    @SuppressWarnings("checkstyle:IllegalCatch")
-    void verifyNoEntityCandidate(final TestActorRef<? extends EntityOwnershipShard> shard, final String entityType,
-            final YangInstanceIdentifier entityId, final String candidateName) {
-        verifyEntityCandidate(entityType, entityId, candidateName, path -> {
-            try {
-                return AbstractShardTest.readStore(shard, path);
-            } catch (Exception e) {
-                throw new AssertionError("Failed to read " + path, e);
-            }
-        }, false);
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/CandidateListChangeListenerTest.java b/opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/CandidateListChangeListenerTest.java
deleted file mode 100644 (file)
index 24cfca6..0000000
+++ /dev/null
@@ -1,117 +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.entityownership;
-
-import static org.junit.Assert.assertEquals;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.ENTITY_OWNERS_PATH;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.candidatePath;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.entityOwnersWithCandidate;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.entityPath;
-
-import akka.testkit.javadsl.TestKit;
-import com.google.common.collect.ImmutableSet;
-import java.time.Duration;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.cluster.datastore.AbstractActorTest;
-import org.opendaylight.controller.cluster.datastore.Shard;
-import org.opendaylight.controller.cluster.datastore.ShardDataTree;
-import org.opendaylight.controller.cluster.entityownership.messages.CandidateAdded;
-import org.opendaylight.controller.cluster.entityownership.messages.CandidateRemoved;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.TreeType;
-
-/**
- * Unit tests for CandidateListChangeListener.
- *
- * @author Thomas Pantelis
- */
-public class CandidateListChangeListenerTest extends AbstractActorTest {
-    private static final String ENTITY_TYPE = "test";
-    private static final YangInstanceIdentifier ENTITY_ID1 =
-            YangInstanceIdentifier.of(QName.create("test", "2015-08-14", "entity1"));
-    private static final YangInstanceIdentifier ENTITY_ID2 =
-            YangInstanceIdentifier.of(QName.create("test", "2015-08-14", "entity2"));
-
-    private ShardDataTree shardDataTree;
-
-    @Mock
-    private Shard mockShard;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        shardDataTree = new ShardDataTree(mockShard, EOSTestUtils.SCHEMA_CONTEXT, TreeType.OPERATIONAL);
-    }
-
-    @Test
-    public void testOnDataTreeChanged() throws Exception {
-        TestKit kit = new TestKit(getSystem());
-
-        new CandidateListChangeListener(kit.getRef(), "test").init(shardDataTree);
-
-        String memberName1 = "member-1";
-        writeNode(ENTITY_OWNERS_PATH, entityOwnersWithCandidate(ENTITY_TYPE, ENTITY_ID1, memberName1));
-
-        CandidateAdded candidateAdded = kit.expectMsgClass(CandidateAdded.class);
-        assertEquals("getEntityId", entityPath(ENTITY_TYPE, ENTITY_ID1), candidateAdded.getEntityPath());
-        assertEquals("getNewCandidate", memberName1, candidateAdded.getNewCandidate());
-        assertEquals("getAllCandidates", ImmutableSet.of(memberName1),
-                ImmutableSet.copyOf(candidateAdded.getAllCandidates()));
-
-        writeNode(ENTITY_OWNERS_PATH, entityOwnersWithCandidate(ENTITY_TYPE, ENTITY_ID1, memberName1));
-        kit.expectNoMessage(Duration.ofMillis(500));
-
-        String memberName2 = "member-2";
-        writeNode(ENTITY_OWNERS_PATH, entityOwnersWithCandidate(ENTITY_TYPE, ENTITY_ID1, memberName2));
-
-        candidateAdded = kit.expectMsgClass(CandidateAdded.class);
-        assertEquals("getEntityId", entityPath(ENTITY_TYPE, ENTITY_ID1), candidateAdded.getEntityPath());
-        assertEquals("getNewCandidate", memberName2, candidateAdded.getNewCandidate());
-        assertEquals("getAllCandidates", ImmutableSet.of(memberName1, memberName2),
-                ImmutableSet.copyOf(candidateAdded.getAllCandidates()));
-
-        writeNode(ENTITY_OWNERS_PATH, entityOwnersWithCandidate(ENTITY_TYPE, ENTITY_ID2, memberName1));
-
-        candidateAdded = kit.expectMsgClass(CandidateAdded.class);
-        assertEquals("getEntityId", entityPath(ENTITY_TYPE, ENTITY_ID2), candidateAdded.getEntityPath());
-        assertEquals("getNewCandidate", memberName1, candidateAdded.getNewCandidate());
-        assertEquals("getAllCandidates", ImmutableSet.of(memberName1),
-                ImmutableSet.copyOf(candidateAdded.getAllCandidates()));
-
-        deleteNode(candidatePath(ENTITY_TYPE, ENTITY_ID1, memberName1));
-
-        CandidateRemoved candidateRemoved = kit.expectMsgClass(CandidateRemoved.class);
-        assertEquals("getEntityId", entityPath(ENTITY_TYPE, ENTITY_ID1), candidateRemoved.getEntityPath());
-        assertEquals("getRemovedCandidate", memberName1, candidateRemoved.getRemovedCandidate());
-        assertEquals("getRemainingCandidates", ImmutableSet.of(memberName2),
-                ImmutableSet.copyOf(candidateRemoved.getRemainingCandidates()));
-
-        deleteNode(candidatePath(ENTITY_TYPE, ENTITY_ID1, memberName2));
-
-        candidateRemoved = kit.expectMsgClass(CandidateRemoved.class);
-        assertEquals("getEntityId", entityPath(ENTITY_TYPE, ENTITY_ID1), candidateRemoved.getEntityPath());
-        assertEquals("getRemovedCandidate", memberName2, candidateRemoved.getRemovedCandidate());
-        assertEquals("getRemainingCandidates", ImmutableSet.of(),
-                ImmutableSet.copyOf(candidateRemoved.getRemainingCandidates()));
-    }
-
-    private void writeNode(final YangInstanceIdentifier path, final NormalizedNode node)
-            throws DataValidationFailedException {
-        AbstractEntityOwnershipTest.writeNode(path, node, shardDataTree);
-    }
-
-    private void deleteNode(final YangInstanceIdentifier path) throws DataValidationFailedException {
-        AbstractEntityOwnershipTest.deleteNode(path, shardDataTree);
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/DistributedEntityOwnershipIntegrationTest.java b/opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/DistributedEntityOwnershipIntegrationTest.java
deleted file mode 100644 (file)
index bcef25e..0000000
+++ /dev/null
@@ -1,883 +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.entityownership;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.AdditionalMatchers.or;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.verify;
-import static org.opendaylight.controller.cluster.datastore.MemberNode.verifyRaftState;
-import static org.opendaylight.controller.cluster.entityownership.AbstractEntityOwnershipTest.ownershipChange;
-import static org.opendaylight.controller.cluster.entityownership.DistributedEntityOwnershipService.ENTITY_OWNERSHIP_SHARD_NAME;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.CANDIDATE_NAME_NODE_ID;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.entityPath;
-
-import akka.actor.ActorRef;
-import akka.actor.Status.Failure;
-import akka.actor.Status.Success;
-import akka.cluster.Cluster;
-import akka.pattern.Patterns;
-import akka.util.Timeout;
-import com.google.common.base.Stopwatch;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.Uninterruptibles;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Optional;
-import java.util.concurrent.TimeUnit;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.mockito.exceptions.base.MockitoException;
-import org.opendaylight.controller.cluster.datastore.AbstractDataStore;
-import org.opendaylight.controller.cluster.datastore.DatastoreContext;
-import org.opendaylight.controller.cluster.datastore.IntegrationTestKit;
-import org.opendaylight.controller.cluster.datastore.MemberNode;
-import org.opendaylight.controller.cluster.datastore.messages.AddShardReplica;
-import org.opendaylight.controller.cluster.datastore.messages.ChangeShardMembersVotingStatus;
-import org.opendaylight.controller.cluster.entityownership.selectionstrategy.EntityOwnerSelectionStrategyConfig;
-import org.opendaylight.controller.cluster.raft.policy.DisableElectionsRaftPolicy;
-import org.opendaylight.controller.cluster.raft.utils.InMemoryJournal;
-import org.opendaylight.controller.cluster.raft.utils.InMemorySnapshotStore;
-import org.opendaylight.mdsal.eos.common.api.EntityOwnershipState;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntity;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipCandidateRegistration;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipChange;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipListener;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.clustering.entity.owners.rev150804.entity.owners.entity.type.entity.Candidate;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import scala.concurrent.Await;
-import scala.concurrent.Future;
-import scala.concurrent.duration.FiniteDuration;
-
-/**
- * End-to-end integration tests for the entity ownership functionality.
- *
- * @author Thomas Pantelis
- */
-public class DistributedEntityOwnershipIntegrationTest {
-    private static final String MODULE_SHARDS_CONFIG = "module-shards-default.conf";
-    private static final String MODULE_SHARDS_5_NODE_CONFIG = "module-shards-default-5-node.conf";
-    private static final String MODULE_SHARDS_MEMBER_1_CONFIG = "module-shards-default-member-1.conf";
-    private static final String ENTITY_TYPE1 = "entityType1";
-    private static final String ENTITY_TYPE2 = "entityType2";
-    private static final DOMEntity ENTITY1 = new DOMEntity(ENTITY_TYPE1, "entity1");
-    private static final DOMEntity ENTITY1_2 = new DOMEntity(ENTITY_TYPE2, "entity1");
-    private static final DOMEntity ENTITY2 = new DOMEntity(ENTITY_TYPE1, "entity2");
-    private static final DOMEntity ENTITY3 = new DOMEntity(ENTITY_TYPE1, "entity3");
-    private static final DOMEntity ENTITY4 = new DOMEntity(ENTITY_TYPE1, "entity4");
-    private final DatastoreContext.Builder leaderDatastoreContextBuilder =
-            DatastoreContext.newBuilder().shardHeartbeatIntervalInMillis(100).shardElectionTimeoutFactor(5)
-                    .shardIsolatedLeaderCheckIntervalInMillis(1000000);
-
-    private final DatastoreContext.Builder followerDatastoreContextBuilder =
-            DatastoreContext.newBuilder().shardHeartbeatIntervalInMillis(100).shardElectionTimeoutFactor(10000);
-
-    private final List<MemberNode> memberNodes = new ArrayList<>();
-
-    @Mock
-    private DOMEntityOwnershipListener leaderMockListener;
-
-    @Mock
-    private DOMEntityOwnershipListener leaderMockListener2;
-
-    @Mock
-    private DOMEntityOwnershipListener follower1MockListener;
-
-    @Mock
-    private DOMEntityOwnershipListener follower2MockListener;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        InMemoryJournal.clear();
-        InMemorySnapshotStore.clear();
-    }
-
-    @After
-    public void tearDown() {
-        for (MemberNode m : Lists.reverse(memberNodes)) {
-            m.cleanup();
-        }
-        memberNodes.clear();
-    }
-
-    private static DistributedEntityOwnershipService newOwnershipService(final AbstractDataStore datastore) {
-        return DistributedEntityOwnershipService.start(datastore.getActorUtils(),
-                EntityOwnerSelectionStrategyConfig.newBuilder().build());
-    }
-
-    @Test
-    public void testFunctionalityWithThreeNodes() throws Exception {
-        String name = "testFunctionalityWithThreeNodes";
-        MemberNode leaderNode = MemberNode.builder(memberNodes).akkaConfig("Member1").testName(name)
-                .moduleShardsConfig(MODULE_SHARDS_CONFIG).schemaContext(EOSTestUtils.SCHEMA_CONTEXT)
-                .createOperDatastore(false).datastoreContextBuilder(leaderDatastoreContextBuilder).build();
-
-        MemberNode follower1Node = MemberNode.builder(memberNodes).akkaConfig("Member2").testName(name)
-                .moduleShardsConfig(MODULE_SHARDS_CONFIG).schemaContext(EOSTestUtils.SCHEMA_CONTEXT)
-                .createOperDatastore(false).datastoreContextBuilder(followerDatastoreContextBuilder).build();
-
-        MemberNode follower2Node = MemberNode.builder(memberNodes).akkaConfig("Member3").testName(name)
-                .moduleShardsConfig(MODULE_SHARDS_CONFIG).schemaContext(EOSTestUtils.SCHEMA_CONTEXT)
-                .createOperDatastore(false).datastoreContextBuilder(followerDatastoreContextBuilder).build();
-
-        AbstractDataStore leaderDistributedDataStore = leaderNode.configDataStore();
-
-        leaderDistributedDataStore.waitTillReady();
-        follower1Node.configDataStore().waitTillReady();
-        follower2Node.configDataStore().waitTillReady();
-
-        final DOMEntityOwnershipService leaderEntityOwnershipService = newOwnershipService(leaderDistributedDataStore);
-        final DOMEntityOwnershipService follower1EntityOwnershipService =
-                newOwnershipService(follower1Node.configDataStore());
-        final DOMEntityOwnershipService follower2EntityOwnershipService =
-                newOwnershipService(follower2Node.configDataStore());
-
-        leaderNode.kit().waitUntilLeader(leaderNode.configDataStore().getActorUtils(), ENTITY_OWNERSHIP_SHARD_NAME);
-
-        leaderEntityOwnershipService.registerListener(ENTITY_TYPE1, leaderMockListener);
-        leaderEntityOwnershipService.registerListener(ENTITY_TYPE2, leaderMockListener2);
-        follower1EntityOwnershipService.registerListener(ENTITY_TYPE1, follower1MockListener);
-
-        // Register leader candidate for entity1 and verify it becomes owner
-
-        leaderEntityOwnershipService.registerCandidate(ENTITY1);
-        verify(leaderMockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY1, false, true, true));
-        verify(follower1MockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY1, false, false, true));
-        reset(leaderMockListener, follower1MockListener);
-
-        verifyGetOwnershipState(leaderEntityOwnershipService, ENTITY1, EntityOwnershipState.IS_OWNER);
-        verifyGetOwnershipState(follower1EntityOwnershipService, ENTITY1, EntityOwnershipState.OWNED_BY_OTHER);
-
-        // Register leader candidate for entity1_2 (same id, different type) and verify it becomes owner
-
-        leaderEntityOwnershipService.registerCandidate(ENTITY1_2);
-        verify(leaderMockListener2, timeout(5000)).ownershipChanged(ownershipChange(ENTITY1_2, false, true, true));
-        Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
-        verify(leaderMockListener, never()).ownershipChanged(ownershipChange(ENTITY1_2));
-        reset(leaderMockListener2);
-
-        // Register follower1 candidate for entity1 and verify it gets added but doesn't become owner
-
-        follower1EntityOwnershipService.registerCandidate(ENTITY1);
-        verifyCandidates(leaderDistributedDataStore, ENTITY1, "member-1", "member-2");
-        verifyOwner(leaderDistributedDataStore, ENTITY1, "member-1");
-        verifyOwner(follower2Node.configDataStore(), ENTITY1, "member-1");
-        Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
-        verify(leaderMockListener, never()).ownershipChanged(ownershipChange(ENTITY1));
-        verify(follower1MockListener, never()).ownershipChanged(ownershipChange(ENTITY1));
-
-        // Register follower1 candidate for entity2 and verify it becomes owner
-
-        final DOMEntityOwnershipCandidateRegistration follower1Entity2Reg =
-                follower1EntityOwnershipService.registerCandidate(ENTITY2);
-        verify(follower1MockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY2, false, true, true));
-        verify(leaderMockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY2, false, false, true));
-        verifyOwner(follower2Node.configDataStore(), ENTITY2, "member-2");
-        reset(leaderMockListener, follower1MockListener);
-
-        // Register follower2 candidate for entity2 and verify it gets added but doesn't become owner
-
-        follower2EntityOwnershipService.registerListener(ENTITY_TYPE1, follower2MockListener);
-        verify(follower2MockListener, timeout(5000).times(2)).ownershipChanged(or(
-                ownershipChange(ENTITY1, false, false, true), ownershipChange(ENTITY2, false, false, true)));
-
-        follower2EntityOwnershipService.registerCandidate(ENTITY2);
-        verifyCandidates(leaderDistributedDataStore, ENTITY2, "member-2", "member-3");
-        verifyOwner(leaderDistributedDataStore, ENTITY2, "member-2");
-
-        // Unregister follower1 candidate for entity2 and verify follower2 becomes owner
-
-        follower1Entity2Reg.close();
-        verifyCandidates(leaderDistributedDataStore, ENTITY2, "member-3");
-        verifyOwner(leaderDistributedDataStore, ENTITY2, "member-3");
-        verify(follower1MockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY2, true, false, true));
-        verify(leaderMockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY2, false, false, true));
-
-        // Depending on timing, follower2MockListener could get ownershipChanged with "false, false, true" if
-        // if the original ownership change with "member-2 is replicated to follower2 after the listener is
-        // registered.
-        Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS);
-        verify(follower2MockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY2, false, true, true));
-
-        // Register follower1 candidate for entity3 and verify it becomes owner
-
-        follower1EntityOwnershipService.registerCandidate(ENTITY3);
-        verifyOwner(leaderDistributedDataStore, ENTITY3, "member-2");
-        verify(follower1MockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY3, false, true, true));
-        verify(follower2MockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY3, false, false, true));
-        verify(leaderMockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY3, false, false, true));
-
-        // Register follower2 candidate for entity4 and verify it becomes owner
-
-        follower2EntityOwnershipService.registerCandidate(ENTITY4);
-        verifyOwner(leaderDistributedDataStore, ENTITY4, "member-3");
-        verify(follower2MockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY4, false, true, true));
-        verify(follower1MockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY4, false, false, true));
-        verify(leaderMockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY4, false, false, true));
-        reset(follower1MockListener, follower2MockListener);
-
-        // Register follower1 candidate for entity4 and verify it gets added but doesn't become owner
-
-        follower1EntityOwnershipService.registerCandidate(ENTITY4);
-        verifyCandidates(leaderDistributedDataStore, ENTITY4, "member-3", "member-2");
-        verifyOwner(leaderDistributedDataStore, ENTITY4, "member-3");
-
-        // Shutdown follower2 and verify it's owned entities (entity 4) get re-assigned
-
-        reset(leaderMockListener, follower1MockListener);
-        follower2Node.cleanup();
-
-        verify(follower1MockListener, timeout(15000)).ownershipChanged(ownershipChange(ENTITY4, false, true, true));
-        verify(leaderMockListener, timeout(15000)).ownershipChanged(ownershipChange(ENTITY4, false, false, true));
-
-        // Register leader candidate for entity2 and verify it becomes owner
-
-        DOMEntityOwnershipCandidateRegistration leaderEntity2Reg =
-                leaderEntityOwnershipService.registerCandidate(ENTITY2);
-        verifyOwner(leaderDistributedDataStore, ENTITY2, "member-1");
-        verify(leaderMockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY2, false, true, true));
-
-        // Unregister leader candidate for entity2 and verify the owner is cleared
-
-        leaderEntity2Reg.close();
-        verifyOwner(leaderDistributedDataStore, ENTITY2, "");
-        verify(leaderMockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY2, true, false, false));
-        verify(follower1MockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY2, false, false, false));
-    }
-
-    @Test
-    public void testLeaderEntityOwnersReassignedAfterShutdown() throws Exception {
-        followerDatastoreContextBuilder.shardElectionTimeoutFactor(5)
-                    .customRaftPolicyImplementation(DisableElectionsRaftPolicy.class.getName());
-
-        String name = "testLeaderEntityOwnersReassignedAfterShutdown";
-        MemberNode leaderNode = MemberNode.builder(memberNodes).akkaConfig("Member1").testName(name)
-                .moduleShardsConfig(MODULE_SHARDS_CONFIG).schemaContext(EOSTestUtils.SCHEMA_CONTEXT)
-                .createOperDatastore(false).datastoreContextBuilder(leaderDatastoreContextBuilder).build();
-
-        MemberNode follower1Node = MemberNode.builder(memberNodes).akkaConfig("Member2").testName(name)
-                .moduleShardsConfig(MODULE_SHARDS_CONFIG).schemaContext(EOSTestUtils.SCHEMA_CONTEXT)
-                .createOperDatastore(false).datastoreContextBuilder(followerDatastoreContextBuilder).build();
-
-        MemberNode follower2Node = MemberNode.builder(memberNodes).akkaConfig("Member3").testName(name)
-                .moduleShardsConfig(MODULE_SHARDS_CONFIG).schemaContext(EOSTestUtils.SCHEMA_CONTEXT)
-                .createOperDatastore(false).datastoreContextBuilder(followerDatastoreContextBuilder).build();
-
-        AbstractDataStore leaderDistributedDataStore = leaderNode.configDataStore();
-
-        leaderDistributedDataStore.waitTillReady();
-        follower1Node.configDataStore().waitTillReady();
-        follower2Node.configDataStore().waitTillReady();
-
-        follower1Node.waitForMembersUp("member-1", "member-3");
-
-        final DOMEntityOwnershipService leaderEntityOwnershipService = newOwnershipService(leaderDistributedDataStore);
-        final DOMEntityOwnershipService follower1EntityOwnershipService =
-                newOwnershipService(follower1Node.configDataStore());
-        final DOMEntityOwnershipService follower2EntityOwnershipService =
-                newOwnershipService(follower2Node.configDataStore());
-
-        leaderNode.kit().waitUntilLeader(leaderNode.configDataStore().getActorUtils(), ENTITY_OWNERSHIP_SHARD_NAME);
-
-        // Register follower1 candidate for entity1 and verify it becomes owner
-
-        follower1EntityOwnershipService.registerCandidate(ENTITY1);
-        verifyOwner(leaderDistributedDataStore, ENTITY1, "member-2");
-
-        // Register leader candidate for entity1
-
-        leaderEntityOwnershipService.registerCandidate(ENTITY1);
-        verifyCandidates(leaderDistributedDataStore, ENTITY1, "member-2", "member-1");
-        verifyOwner(leaderDistributedDataStore, ENTITY1, "member-2");
-
-        // Register leader candidate for entity2 and verify it becomes owner
-
-        leaderEntityOwnershipService.registerCandidate(ENTITY2);
-        verifyOwner(leaderDistributedDataStore, ENTITY2, "member-1");
-
-        // Register follower2 candidate for entity2
-
-        follower2EntityOwnershipService.registerCandidate(ENTITY2);
-        verifyCandidates(leaderDistributedDataStore, ENTITY2, "member-1", "member-3");
-        verifyOwner(leaderDistributedDataStore, ENTITY2, "member-1");
-
-        // Re-enable elections on all remaining followers so one becomes the new leader
-
-        ActorRef follower1Shard = IntegrationTestKit.findLocalShard(follower1Node.configDataStore().getActorUtils(),
-                ENTITY_OWNERSHIP_SHARD_NAME);
-        follower1Shard.tell(DatastoreContext.newBuilderFrom(followerDatastoreContextBuilder.build())
-                .customRaftPolicyImplementation(null).build(), ActorRef.noSender());
-
-        ActorRef follower2Shard = IntegrationTestKit.findLocalShard(follower2Node.configDataStore().getActorUtils(),
-                ENTITY_OWNERSHIP_SHARD_NAME);
-        follower2Shard.tell(DatastoreContext.newBuilderFrom(followerDatastoreContextBuilder.build())
-                .customRaftPolicyImplementation(null).build(), ActorRef.noSender());
-
-        // Shutdown the leader and verify its removed from the candidate list
-
-        leaderNode.cleanup();
-        follower1Node.waitForMemberDown("member-1");
-        follower2Node.waitForMemberDown("member-1");
-
-        // Verify the prior leader's entity owners are re-assigned.
-
-        verifyCandidates(follower1Node.configDataStore(), ENTITY1, "member-2", "member-1");
-        verifyCandidates(follower1Node.configDataStore(), ENTITY2, "member-1", "member-3");
-        verifyOwner(follower1Node.configDataStore(), ENTITY1, "member-2");
-        verifyOwner(follower1Node.configDataStore(), ENTITY2, "member-3");
-    }
-
-    @Test
-    public void testLeaderAndFollowerEntityOwnersReassignedAfterShutdown() throws Exception {
-        followerDatastoreContextBuilder.shardElectionTimeoutFactor(5)
-                .customRaftPolicyImplementation(DisableElectionsRaftPolicy.class.getName());
-
-        String name = "testLeaderAndFollowerEntityOwnersReassignedAfterShutdown";
-        final MemberNode leaderNode = MemberNode.builder(memberNodes).akkaConfig("Member1")
-                .useAkkaArtery(false).testName(name)
-                .moduleShardsConfig(MODULE_SHARDS_5_NODE_CONFIG)
-                .schemaContext(EOSTestUtils.SCHEMA_CONTEXT)
-                .createOperDatastore(false).datastoreContextBuilder(leaderDatastoreContextBuilder).build();
-
-        final MemberNode follower1Node = MemberNode.builder(memberNodes).akkaConfig("Member2")
-                .testName(name).moduleShardsConfig(MODULE_SHARDS_5_NODE_CONFIG)
-                .useAkkaArtery(false).schemaContext(EOSTestUtils.SCHEMA_CONTEXT)
-                .createOperDatastore(false).datastoreContextBuilder(followerDatastoreContextBuilder).build();
-
-        final MemberNode follower2Node = MemberNode.builder(memberNodes).akkaConfig("Member3")
-                .testName(name).moduleShardsConfig(MODULE_SHARDS_5_NODE_CONFIG)
-                .useAkkaArtery(false).schemaContext(EOSTestUtils.SCHEMA_CONTEXT)
-                .createOperDatastore(false).datastoreContextBuilder(followerDatastoreContextBuilder).build();
-
-        final MemberNode follower3Node = MemberNode.builder(memberNodes).akkaConfig("Member4")
-                .testName(name).moduleShardsConfig(MODULE_SHARDS_5_NODE_CONFIG)
-                .useAkkaArtery(false).schemaContext(EOSTestUtils.SCHEMA_CONTEXT)
-                .createOperDatastore(false).datastoreContextBuilder(followerDatastoreContextBuilder).build();
-
-        final MemberNode follower4Node = MemberNode.builder(memberNodes).akkaConfig("Member5")
-                .testName(name).moduleShardsConfig(MODULE_SHARDS_5_NODE_CONFIG)
-                .useAkkaArtery(false).schemaContext(EOSTestUtils.SCHEMA_CONTEXT)
-                .createOperDatastore(false).datastoreContextBuilder(followerDatastoreContextBuilder).build();
-
-        AbstractDataStore leaderDistributedDataStore = leaderNode.configDataStore();
-
-        leaderDistributedDataStore.waitTillReady();
-        follower1Node.configDataStore().waitTillReady();
-        follower2Node.configDataStore().waitTillReady();
-        follower3Node.configDataStore().waitTillReady();
-        follower4Node.configDataStore().waitTillReady();
-
-        leaderNode.waitForMembersUp("member-2", "member-3", "member-4", "member-5");
-        follower1Node.waitForMembersUp("member-1", "member-3", "member-4", "member-5");
-
-        final DOMEntityOwnershipService leaderEntityOwnershipService = newOwnershipService(leaderDistributedDataStore);
-        final DOMEntityOwnershipService follower1EntityOwnershipService =
-                newOwnershipService(follower1Node.configDataStore());
-        final DOMEntityOwnershipService follower2EntityOwnershipService =
-                newOwnershipService(follower2Node.configDataStore());
-        final DOMEntityOwnershipService follower3EntityOwnershipService =
-                newOwnershipService(follower3Node.configDataStore());
-        newOwnershipService(follower4Node.configDataStore());
-
-        leaderNode.kit().waitUntilLeader(leaderNode.configDataStore().getActorUtils(), ENTITY_OWNERSHIP_SHARD_NAME);
-
-        // Register follower1 candidate for entity1 and verify it becomes owner
-
-        follower1EntityOwnershipService.registerCandidate(ENTITY1);
-        verifyOwner(leaderDistributedDataStore, ENTITY1, "member-2");
-
-        // Register leader candidate for entity1
-
-        leaderEntityOwnershipService.registerCandidate(ENTITY1);
-        verifyCandidates(leaderDistributedDataStore, ENTITY1, "member-2", "member-1");
-        verifyOwner(leaderDistributedDataStore, ENTITY1, "member-2");
-
-        // Register leader candidate for entity2 and verify it becomes owner
-
-        leaderEntityOwnershipService.registerCandidate(ENTITY2);
-        verifyOwner(leaderDistributedDataStore, ENTITY2, "member-1");
-
-        // Register follower2 candidate for entity2
-
-        follower2EntityOwnershipService.registerCandidate(ENTITY2);
-        verifyCandidates(leaderDistributedDataStore, ENTITY2, "member-1", "member-3");
-        verifyOwner(leaderDistributedDataStore, ENTITY2, "member-1");
-
-        // Register follower3 as a candidate for entity2 as well
-
-        follower3EntityOwnershipService.registerCandidate(ENTITY2);
-        verifyCandidates(leaderDistributedDataStore, ENTITY2, "member-1", "member-3", "member-4");
-        verifyOwner(leaderDistributedDataStore, ENTITY2, "member-1");
-
-        // Re-enable elections on all remaining followers so one becomes the new leader
-
-        ActorRef follower1Shard = IntegrationTestKit.findLocalShard(follower1Node.configDataStore().getActorUtils(),
-                ENTITY_OWNERSHIP_SHARD_NAME);
-        follower1Shard.tell(DatastoreContext.newBuilderFrom(followerDatastoreContextBuilder.build())
-                .customRaftPolicyImplementation(null).build(), ActorRef.noSender());
-
-        ActorRef follower2Shard = IntegrationTestKit.findLocalShard(follower2Node.configDataStore().getActorUtils(),
-                ENTITY_OWNERSHIP_SHARD_NAME);
-        follower2Shard.tell(DatastoreContext.newBuilderFrom(followerDatastoreContextBuilder.build())
-                .customRaftPolicyImplementation(null).build(), ActorRef.noSender());
-
-        ActorRef follower4Shard = IntegrationTestKit.findLocalShard(follower4Node.configDataStore().getActorUtils(),
-                ENTITY_OWNERSHIP_SHARD_NAME);
-        follower4Shard.tell(DatastoreContext.newBuilderFrom(followerDatastoreContextBuilder.build())
-                .customRaftPolicyImplementation(null).build(), ActorRef.noSender());
-
-        // Shutdown the leader and follower3
-
-        leaderNode.cleanup();
-
-        follower1Node.waitForMemberDown("member-1");
-        follower2Node.waitForMemberDown("member-1");
-        follower4Node.waitForMemberDown("member-1");
-
-        follower3Node.cleanup();
-
-        follower1Node.waitForMemberDown("member-4");
-        follower2Node.waitForMemberDown("member-4");
-        follower4Node.waitForMemberDown("member-4");
-
-        // Verify the prior leader's and follower3 entity owners are re-assigned.
-
-        verifyCandidates(follower1Node.configDataStore(), ENTITY1, "member-2", "member-1");
-        verifyCandidates(follower1Node.configDataStore(), ENTITY2, "member-1", "member-3", "member-4");
-        verifyOwner(follower1Node.configDataStore(), ENTITY1, "member-2");
-        verifyOwner(follower1Node.configDataStore(), ENTITY2, "member-3");
-    }
-
-    /**
-     * Reproduces bug <a href="https://bugs.opendaylight.org/show_bug.cgi?id=4554">4554</a>.
-     */
-    @Test
-    public void testCloseCandidateRegistrationInQuickSuccession() throws Exception {
-        String name = "testCloseCandidateRegistrationInQuickSuccession";
-        MemberNode leaderNode = MemberNode.builder(memberNodes).akkaConfig("Member1").testName(name)
-                .moduleShardsConfig(MODULE_SHARDS_CONFIG).schemaContext(EOSTestUtils.SCHEMA_CONTEXT)
-                .createOperDatastore(false).datastoreContextBuilder(leaderDatastoreContextBuilder).build();
-
-        MemberNode follower1Node = MemberNode.builder(memberNodes).akkaConfig("Member2").testName(name)
-                .moduleShardsConfig(MODULE_SHARDS_CONFIG).schemaContext(EOSTestUtils.SCHEMA_CONTEXT)
-                .createOperDatastore(false).datastoreContextBuilder(followerDatastoreContextBuilder).build();
-
-        MemberNode follower2Node = MemberNode.builder(memberNodes).akkaConfig("Member3").testName(name)
-                .moduleShardsConfig(MODULE_SHARDS_CONFIG).schemaContext(EOSTestUtils.SCHEMA_CONTEXT)
-                .createOperDatastore(false).datastoreContextBuilder(followerDatastoreContextBuilder).build();
-
-        AbstractDataStore leaderDistributedDataStore = leaderNode.configDataStore();
-
-        leaderDistributedDataStore.waitTillReady();
-        follower1Node.configDataStore().waitTillReady();
-        follower2Node.configDataStore().waitTillReady();
-
-        final DOMEntityOwnershipService leaderEntityOwnershipService = newOwnershipService(leaderDistributedDataStore);
-        final DOMEntityOwnershipService follower1EntityOwnershipService =
-                newOwnershipService(follower1Node.configDataStore());
-        final DOMEntityOwnershipService follower2EntityOwnershipService =
-                newOwnershipService(follower2Node.configDataStore());
-
-        leaderNode.kit().waitUntilLeader(leaderNode.configDataStore().getActorUtils(), ENTITY_OWNERSHIP_SHARD_NAME);
-
-        leaderEntityOwnershipService.registerListener(ENTITY_TYPE1, leaderMockListener);
-        follower1EntityOwnershipService.registerListener(ENTITY_TYPE1, follower1MockListener);
-        follower2EntityOwnershipService.registerListener(ENTITY_TYPE1, follower2MockListener);
-
-        final DOMEntityOwnershipCandidateRegistration candidate1 =
-                leaderEntityOwnershipService.registerCandidate(ENTITY1);
-        verify(leaderMockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY1, false, true, true));
-
-        final DOMEntityOwnershipCandidateRegistration candidate2 =
-                follower1EntityOwnershipService.registerCandidate(ENTITY1);
-        verify(follower1MockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY1, false, false, true));
-
-        final DOMEntityOwnershipCandidateRegistration candidate3 =
-                follower2EntityOwnershipService.registerCandidate(ENTITY1);
-        verify(follower2MockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY1, false, false, true));
-
-        Mockito.reset(leaderMockListener, follower1MockListener, follower2MockListener);
-
-        ArgumentCaptor<DOMEntityOwnershipChange> leaderChangeCaptor =
-                ArgumentCaptor.forClass(DOMEntityOwnershipChange.class);
-        ArgumentCaptor<DOMEntityOwnershipChange> follower1ChangeCaptor =
-                ArgumentCaptor.forClass(DOMEntityOwnershipChange.class);
-        ArgumentCaptor<DOMEntityOwnershipChange> follower2ChangeCaptor =
-                ArgumentCaptor.forClass(DOMEntityOwnershipChange.class);
-        doNothing().when(leaderMockListener).ownershipChanged(leaderChangeCaptor.capture());
-        doNothing().when(follower1MockListener).ownershipChanged(follower1ChangeCaptor.capture());
-        doNothing().when(follower2MockListener).ownershipChanged(follower2ChangeCaptor.capture());
-
-        candidate1.close();
-        candidate2.close();
-        candidate3.close();
-
-        boolean passed = false;
-        for (int i = 0; i < 100; i++) {
-            Uninterruptibles.sleepUninterruptibly(50, TimeUnit.MILLISECONDS);
-            final Optional<EntityOwnershipState> leaderState = leaderEntityOwnershipService.getOwnershipState(ENTITY1);
-            final Optional<EntityOwnershipState> follower1State =
-                    follower1EntityOwnershipService.getOwnershipState(ENTITY1);
-            final Optional<EntityOwnershipState> follower2State =
-                    follower2EntityOwnershipService.getOwnershipState(ENTITY1);
-            final Optional<DOMEntityOwnershipChange> leaderChange = getValueSafely(leaderChangeCaptor);
-            final Optional<DOMEntityOwnershipChange> follower1Change = getValueSafely(follower1ChangeCaptor);
-            final Optional<DOMEntityOwnershipChange> follower2Change = getValueSafely(follower2ChangeCaptor);
-            if (!leaderState.isPresent() || leaderState.get() == EntityOwnershipState.NO_OWNER
-                    && follower1State.isPresent() && follower1State.get() == EntityOwnershipState.NO_OWNER
-                    && follower2State.isPresent() && follower2State.get() == EntityOwnershipState.NO_OWNER
-                    && leaderChange.isPresent() && !leaderChange.get().getState().hasOwner()
-                    && follower1Change.isPresent() && !follower1Change.get().getState().hasOwner()
-                    && follower2Change.isPresent() && !follower2Change.get().getState().hasOwner()) {
-                passed = true;
-                break;
-            }
-        }
-
-        assertTrue("No ownership change message was sent with hasOwner=false", passed);
-    }
-
-    private static Optional<DOMEntityOwnershipChange> getValueSafely(
-            final ArgumentCaptor<DOMEntityOwnershipChange> captor) {
-        try {
-            return Optional.ofNullable(captor.getValue());
-        } catch (MockitoException e) {
-            // No value was captured
-            return Optional.empty();
-        }
-    }
-
-    /**
-     * Tests bootstrapping the entity-ownership shard when there's no shards initially configured for local
-     * member. The entity-ownership shard is initially created as inactive (ie remains a follower), requiring
-     * an AddShardReplica request to join it to an existing leader.
-     */
-    @Test
-    public void testEntityOwnershipShardBootstrapping() throws Exception {
-        String name = "testEntityOwnershipShardBootstrapping";
-        String moduleShardsConfig = MODULE_SHARDS_MEMBER_1_CONFIG;
-        MemberNode leaderNode = MemberNode.builder(memberNodes).akkaConfig("Member1").testName(name)
-                .moduleShardsConfig(moduleShardsConfig).schemaContext(EOSTestUtils.SCHEMA_CONTEXT)
-                .createOperDatastore(false).datastoreContextBuilder(leaderDatastoreContextBuilder).build();
-
-        AbstractDataStore leaderDistributedDataStore = leaderNode.configDataStore();
-        final DOMEntityOwnershipService leaderEntityOwnershipService = newOwnershipService(leaderDistributedDataStore);
-
-        leaderNode.kit().waitUntilLeader(leaderNode.configDataStore().getActorUtils(), ENTITY_OWNERSHIP_SHARD_NAME);
-
-        MemberNode follower1Node = MemberNode.builder(memberNodes).akkaConfig("Member2").testName(name)
-                .moduleShardsConfig(moduleShardsConfig).schemaContext(EOSTestUtils.SCHEMA_CONTEXT)
-                .createOperDatastore(false).datastoreContextBuilder(followerDatastoreContextBuilder).build();
-
-        AbstractDataStore follower1DistributedDataStore = follower1Node.configDataStore();
-        follower1DistributedDataStore.waitTillReady();
-
-        leaderNode.waitForMembersUp("member-2");
-        follower1Node.waitForMembersUp("member-1");
-
-        DOMEntityOwnershipService follower1EntityOwnershipService = newOwnershipService(follower1DistributedDataStore);
-
-        leaderEntityOwnershipService.registerListener(ENTITY_TYPE1, leaderMockListener);
-
-        // Register a candidate for follower1 - should get queued since follower1 has no leader
-        final DOMEntityOwnershipCandidateRegistration candidateReg =
-                follower1EntityOwnershipService.registerCandidate(ENTITY1);
-        Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
-        verify(leaderMockListener, never()).ownershipChanged(ownershipChange(ENTITY1));
-
-        // Add replica in follower1
-        AddShardReplica addReplica = new AddShardReplica(ENTITY_OWNERSHIP_SHARD_NAME);
-        follower1DistributedDataStore.getActorUtils().getShardManager().tell(addReplica,
-                follower1Node.kit().getRef());
-        Object reply = follower1Node.kit().expectMsgAnyClassOf(follower1Node.kit().duration("5 sec"),
-                Success.class, Failure.class);
-        if (reply instanceof Failure) {
-            throw new AssertionError("AddShardReplica failed", ((Failure)reply).cause());
-        }
-
-        // The queued candidate registration should proceed
-        verify(leaderMockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY1, false, false, true));
-        reset(leaderMockListener);
-
-        candidateReg.close();
-        verify(leaderMockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY1, false, false, false));
-        reset(leaderMockListener);
-
-        // Restart follower1 and verify the entity ownership shard is re-instated by registering.
-        Cluster.get(leaderNode.kit().getSystem()).down(Cluster.get(follower1Node.kit().getSystem()).selfAddress());
-        follower1Node.cleanup();
-
-        follower1Node = MemberNode.builder(memberNodes).akkaConfig("Member2").testName(name)
-                .moduleShardsConfig(moduleShardsConfig).schemaContext(EOSTestUtils.SCHEMA_CONTEXT)
-                .createOperDatastore(false).datastoreContextBuilder(followerDatastoreContextBuilder).build();
-        follower1EntityOwnershipService = newOwnershipService(follower1Node.configDataStore());
-
-        follower1EntityOwnershipService.registerCandidate(ENTITY1);
-        verify(leaderMockListener, timeout(20000)).ownershipChanged(ownershipChange(ENTITY1, false, false, true));
-
-        verifyRaftState(follower1Node.configDataStore(), ENTITY_OWNERSHIP_SHARD_NAME, raftState -> {
-            assertNull("Custom RaftPolicy class name", raftState.getCustomRaftPolicyClassName());
-            assertEquals("Peer count", 1, raftState.getPeerAddresses().keySet().size());
-            assertThat("Peer Id", Iterables.<String>getLast(raftState.getPeerAddresses().keySet()),
-                    org.hamcrest.CoreMatchers.containsString("member-1"));
-        });
-    }
-
-    @Test
-    public void testOwnerSelectedOnRapidUnregisteringAndRegisteringOfCandidates() throws Exception {
-        String name = "testOwnerSelectedOnRapidUnregisteringAndRegisteringOfCandidates";
-        MemberNode leaderNode = MemberNode.builder(memberNodes).akkaConfig("Member1").testName(name)
-                .moduleShardsConfig(MODULE_SHARDS_CONFIG).schemaContext(EOSTestUtils.SCHEMA_CONTEXT)
-                .createOperDatastore(false).datastoreContextBuilder(leaderDatastoreContextBuilder).build();
-
-        MemberNode follower1Node = MemberNode.builder(memberNodes).akkaConfig("Member2").testName(name)
-                .moduleShardsConfig(MODULE_SHARDS_CONFIG).schemaContext(EOSTestUtils.SCHEMA_CONTEXT)
-                .createOperDatastore(false).datastoreContextBuilder(followerDatastoreContextBuilder).build();
-
-        MemberNode follower2Node = MemberNode.builder(memberNodes).akkaConfig("Member3").testName(name)
-                .moduleShardsConfig(MODULE_SHARDS_CONFIG).schemaContext(EOSTestUtils.SCHEMA_CONTEXT)
-                .createOperDatastore(false).datastoreContextBuilder(followerDatastoreContextBuilder).build();
-
-        AbstractDataStore leaderDistributedDataStore = leaderNode.configDataStore();
-
-        leaderDistributedDataStore.waitTillReady();
-        follower1Node.configDataStore().waitTillReady();
-        follower2Node.configDataStore().waitTillReady();
-
-        final DOMEntityOwnershipService leaderEntityOwnershipService = newOwnershipService(leaderDistributedDataStore);
-        final DOMEntityOwnershipService follower1EntityOwnershipService =
-                newOwnershipService(follower1Node.configDataStore());
-        newOwnershipService(follower2Node.configDataStore());
-
-        leaderNode.kit().waitUntilLeader(leaderNode.configDataStore().getActorUtils(), ENTITY_OWNERSHIP_SHARD_NAME);
-
-        // Register leader candidate for entity1 and verify it becomes owner
-
-        DOMEntityOwnershipCandidateRegistration leaderEntity1Reg =
-                leaderEntityOwnershipService.registerCandidate(ENTITY1);
-
-        verifyCandidates(leaderDistributedDataStore, ENTITY1, "member-1");
-        verifyOwner(leaderDistributedDataStore, ENTITY1, "member-1");
-
-        leaderEntity1Reg.close();
-        follower1EntityOwnershipService.registerCandidate(ENTITY1);
-
-        verifyCandidates(leaderDistributedDataStore, ENTITY1, "member-2");
-        verifyOwner(leaderDistributedDataStore, ENTITY1, "member-2");
-    }
-
-    @Test
-    public void testOwnerSelectedOnRapidRegisteringAndUnregisteringOfCandidates() throws Exception {
-        String name = "testOwnerSelectedOnRapidRegisteringAndUnregisteringOfCandidates";
-        MemberNode leaderNode = MemberNode.builder(memberNodes).akkaConfig("Member1").testName(name)
-                .moduleShardsConfig(MODULE_SHARDS_CONFIG).schemaContext(EOSTestUtils.SCHEMA_CONTEXT)
-                .createOperDatastore(false).datastoreContextBuilder(leaderDatastoreContextBuilder).build();
-
-        MemberNode follower1Node = MemberNode.builder(memberNodes).akkaConfig("Member2").testName(name)
-                .moduleShardsConfig(MODULE_SHARDS_CONFIG).schemaContext(EOSTestUtils.SCHEMA_CONTEXT)
-                .createOperDatastore(false).datastoreContextBuilder(followerDatastoreContextBuilder).build();
-
-        MemberNode follower2Node = MemberNode.builder(memberNodes).akkaConfig("Member3").testName(name)
-                .moduleShardsConfig(MODULE_SHARDS_CONFIG).schemaContext(EOSTestUtils.SCHEMA_CONTEXT)
-                .createOperDatastore(false).datastoreContextBuilder(followerDatastoreContextBuilder).build();
-
-        AbstractDataStore leaderDistributedDataStore = leaderNode.configDataStore();
-
-        leaderDistributedDataStore.waitTillReady();
-        follower1Node.configDataStore().waitTillReady();
-        follower2Node.configDataStore().waitTillReady();
-
-        final DOMEntityOwnershipService leaderEntityOwnershipService = newOwnershipService(leaderDistributedDataStore);
-        final DOMEntityOwnershipService follower1EntityOwnershipService =
-                newOwnershipService(follower1Node.configDataStore());
-        newOwnershipService(follower2Node.configDataStore());
-
-        leaderNode.kit().waitUntilLeader(leaderNode.configDataStore().getActorUtils(), ENTITY_OWNERSHIP_SHARD_NAME);
-
-        // Register leader candidate for entity1 and verify it becomes owner
-
-        final DOMEntityOwnershipCandidateRegistration leaderEntity1Reg =
-                leaderEntityOwnershipService.registerCandidate(ENTITY1);
-
-        verifyCandidates(leaderDistributedDataStore, ENTITY1, "member-1");
-        verifyOwner(leaderDistributedDataStore, ENTITY1, "member-1");
-
-        follower1EntityOwnershipService.registerCandidate(ENTITY1);
-        leaderEntity1Reg.close();
-
-        verifyCandidates(leaderDistributedDataStore, ENTITY1, "member-2");
-        verifyOwner(leaderDistributedDataStore, ENTITY1, "member-2");
-    }
-
-    @Test
-    public void testEntityOwnershipWithNonVotingMembers() throws Exception {
-        followerDatastoreContextBuilder.shardElectionTimeoutFactor(5)
-                .customRaftPolicyImplementation(DisableElectionsRaftPolicy.class.getName());
-
-        String name = "testEntityOwnershipWithNonVotingMembers";
-        final MemberNode member1LeaderNode = MemberNode.builder(memberNodes).akkaConfig("Member1")
-                .useAkkaArtery(false).testName(name)
-                .moduleShardsConfig(MODULE_SHARDS_5_NODE_CONFIG).schemaContext(EOSTestUtils.SCHEMA_CONTEXT)
-                .createOperDatastore(false).datastoreContextBuilder(leaderDatastoreContextBuilder).build();
-
-        final MemberNode member2FollowerNode = MemberNode.builder(memberNodes).akkaConfig("Member2")
-                .useAkkaArtery(false).testName(name)
-                .moduleShardsConfig(MODULE_SHARDS_5_NODE_CONFIG).schemaContext(EOSTestUtils.SCHEMA_CONTEXT)
-                .createOperDatastore(false).datastoreContextBuilder(followerDatastoreContextBuilder).build();
-
-        final MemberNode member3FollowerNode = MemberNode.builder(memberNodes).akkaConfig("Member3")
-                .useAkkaArtery(false).testName(name)
-                .moduleShardsConfig(MODULE_SHARDS_5_NODE_CONFIG).schemaContext(EOSTestUtils.SCHEMA_CONTEXT)
-                .createOperDatastore(false).datastoreContextBuilder(followerDatastoreContextBuilder).build();
-
-        final MemberNode member4FollowerNode = MemberNode.builder(memberNodes).akkaConfig("Member4")
-                .useAkkaArtery(false).testName(name)
-                .moduleShardsConfig(MODULE_SHARDS_5_NODE_CONFIG).schemaContext(EOSTestUtils.SCHEMA_CONTEXT)
-                .createOperDatastore(false).datastoreContextBuilder(followerDatastoreContextBuilder).build();
-
-        final MemberNode member5FollowerNode = MemberNode.builder(memberNodes).akkaConfig("Member5")
-                .useAkkaArtery(false).testName(name)
-                .moduleShardsConfig(MODULE_SHARDS_5_NODE_CONFIG).schemaContext(EOSTestUtils.SCHEMA_CONTEXT)
-                .createOperDatastore(false).datastoreContextBuilder(followerDatastoreContextBuilder).build();
-
-        AbstractDataStore leaderDistributedDataStore = member1LeaderNode.configDataStore();
-
-        leaderDistributedDataStore.waitTillReady();
-        member2FollowerNode.configDataStore().waitTillReady();
-        member3FollowerNode.configDataStore().waitTillReady();
-        member4FollowerNode.configDataStore().waitTillReady();
-        member5FollowerNode.configDataStore().waitTillReady();
-
-        member1LeaderNode.waitForMembersUp("member-2", "member-3", "member-4", "member-5");
-
-        final DOMEntityOwnershipService member3EntityOwnershipService =
-                newOwnershipService(member3FollowerNode.configDataStore());
-        final DOMEntityOwnershipService member4EntityOwnershipService =
-                newOwnershipService(member4FollowerNode.configDataStore());
-        final DOMEntityOwnershipService member5EntityOwnershipService =
-                newOwnershipService(member5FollowerNode.configDataStore());
-
-        newOwnershipService(member1LeaderNode.configDataStore());
-        member1LeaderNode.kit().waitUntilLeader(member1LeaderNode.configDataStore().getActorUtils(),
-                ENTITY_OWNERSHIP_SHARD_NAME);
-
-        // Make member4 and member5 non-voting
-
-        Future<Object> future = Patterns.ask(leaderDistributedDataStore.getActorUtils().getShardManager(),
-                new ChangeShardMembersVotingStatus(ENTITY_OWNERSHIP_SHARD_NAME,
-                        ImmutableMap.of("member-4", Boolean.FALSE, "member-5", Boolean.FALSE)),
-                new Timeout(10, TimeUnit.SECONDS));
-        Object response = Await.result(future, FiniteDuration.apply(10, TimeUnit.SECONDS));
-        if (response instanceof Throwable) {
-            throw new AssertionError("ChangeShardMembersVotingStatus failed", (Throwable)response);
-        }
-
-        assertNull("Expected null Success response. Actual " + response, response);
-
-        // Register member4 candidate for entity1 - it should not become owner since it's non-voting
-
-        member4EntityOwnershipService.registerCandidate(ENTITY1);
-        verifyCandidates(leaderDistributedDataStore, ENTITY1, "member-4");
-
-        // Register member5 candidate for entity2 - it should not become owner since it's non-voting
-
-        member5EntityOwnershipService.registerCandidate(ENTITY2);
-        verifyCandidates(leaderDistributedDataStore, ENTITY2, "member-5");
-
-        Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS);
-        verifyOwner(leaderDistributedDataStore, ENTITY1, "");
-        verifyOwner(leaderDistributedDataStore, ENTITY2, "");
-
-        // Register member3 candidate for entity1 - it should become owner since it's voting
-
-        member3EntityOwnershipService.registerCandidate(ENTITY1);
-        verifyCandidates(leaderDistributedDataStore, ENTITY1, "member-4", "member-3");
-        verifyOwner(leaderDistributedDataStore, ENTITY1, "member-3");
-
-        // Switch member4 and member5 back to voting and member3 non-voting. This should result in member4 and member5
-        // to become entity owners.
-
-        future = Patterns.ask(leaderDistributedDataStore.getActorUtils().getShardManager(),
-                new ChangeShardMembersVotingStatus(ENTITY_OWNERSHIP_SHARD_NAME,
-                        ImmutableMap.of("member-3", Boolean.FALSE, "member-4", Boolean.TRUE, "member-5", Boolean.TRUE)),
-                new Timeout(10, TimeUnit.SECONDS));
-        response = Await.result(future, FiniteDuration.apply(10, TimeUnit.SECONDS));
-        if (response instanceof Throwable) {
-            throw new AssertionError("ChangeShardMembersVotingStatus failed", (Throwable)response);
-        }
-
-        assertNull("Expected null Success response. Actual " + response, response);
-
-        verifyOwner(leaderDistributedDataStore, ENTITY1, "member-4");
-        verifyOwner(leaderDistributedDataStore, ENTITY2, "member-5");
-    }
-
-    private static void verifyGetOwnershipState(final DOMEntityOwnershipService service, final DOMEntity entity,
-            final EntityOwnershipState expState) {
-        Optional<EntityOwnershipState> state = service.getOwnershipState(entity);
-        assertTrue("getOwnershipState present", state.isPresent());
-        assertEquals("EntityOwnershipState", expState, state.get());
-    }
-
-    private static void verifyCandidates(final AbstractDataStore dataStore, final DOMEntity entity,
-            final String... expCandidates) throws Exception {
-        AssertionError lastError = null;
-        Stopwatch sw = Stopwatch.createStarted();
-        while (sw.elapsed(TimeUnit.MILLISECONDS) <= 10000) {
-            Optional<NormalizedNode> possible = dataStore.newReadOnlyTransaction()
-                    .read(entityPath(entity.getType(), entity.getIdentifier()).node(Candidate.QNAME))
-                    .get(5, TimeUnit.SECONDS);
-            try {
-                assertTrue("Candidates not found for " + entity, possible.isPresent());
-                Collection<String> actual = new ArrayList<>();
-                for (MapEntryNode candidate: ((MapNode)possible.get()).body()) {
-                    actual.add(candidate.findChildByArg(CANDIDATE_NAME_NODE_ID).get().body().toString());
-                }
-
-                assertEquals("Candidates for " + entity, Arrays.asList(expCandidates), actual);
-                return;
-            } catch (AssertionError e) {
-                lastError = e;
-                Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
-            }
-        }
-
-        throw lastError;
-    }
-
-    @SuppressWarnings("checkstyle:IllegalCatch")
-    private static void verifyOwner(final AbstractDataStore dataStore, final DOMEntity entity,
-            final String expOwner) {
-        AbstractEntityOwnershipTest.verifyOwner(expOwner, entity.getType(), entity.getIdentifier(), path -> {
-            try {
-                return dataStore.newReadOnlyTransaction().read(path).get(5, TimeUnit.SECONDS).get();
-            } catch (Exception e) {
-                return null;
-            }
-        });
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/DistributedEntityOwnershipServiceTest.java b/opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/DistributedEntityOwnershipServiceTest.java
deleted file mode 100644 (file)
index 758ce9d..0000000
+++ /dev/null
@@ -1,310 +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.entityownership;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.ENTITY_ID_QNAME;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.ENTITY_OWNERS_PATH;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.ENTITY_QNAME;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.candidatePath;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.entityEntryWithOwner;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.entityOwnersWithCandidate;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.entityOwnersWithEntityTypeEntry;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.entityPath;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.entityTypeEntryWithEntityEntry;
-
-import akka.actor.ActorRef;
-import com.google.common.collect.Sets;
-import java.util.Collection;
-import java.util.Optional;
-import java.util.concurrent.TimeUnit;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mockito;
-import org.opendaylight.controller.cluster.access.concepts.MemberName;
-import org.opendaylight.controller.cluster.datastore.AbstractDataStore;
-import org.opendaylight.controller.cluster.datastore.DatastoreContext;
-import org.opendaylight.controller.cluster.datastore.DatastoreContextFactory;
-import org.opendaylight.controller.cluster.datastore.DistributedDataStore;
-import org.opendaylight.controller.cluster.datastore.Shard;
-import org.opendaylight.controller.cluster.datastore.ShardDataTree;
-import org.opendaylight.controller.cluster.datastore.config.Configuration;
-import org.opendaylight.controller.cluster.datastore.config.ConfigurationImpl;
-import org.opendaylight.controller.cluster.datastore.config.EmptyModuleShardConfigProvider;
-import org.opendaylight.controller.cluster.datastore.utils.MockClusterWrapper;
-import org.opendaylight.controller.cluster.entityownership.messages.RegisterCandidateLocal;
-import org.opendaylight.controller.cluster.entityownership.messages.RegisterListenerLocal;
-import org.opendaylight.controller.cluster.entityownership.messages.UnregisterCandidateLocal;
-import org.opendaylight.controller.cluster.entityownership.messages.UnregisterListenerLocal;
-import org.opendaylight.controller.cluster.entityownership.selectionstrategy.EntityOwnerSelectionStrategyConfig;
-import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException;
-import org.opendaylight.mdsal.eos.common.api.EntityOwnershipState;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntity;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipCandidateRegistration;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipListener;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipListenerRegistration;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.TreeType;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-import scala.concurrent.Await;
-import scala.concurrent.Future;
-import scala.concurrent.duration.FiniteDuration;
-
-/**
- * Unit tests for DistributedEntityOwnershipService.
- *
- * @author Thomas Pantelis
- */
-public class DistributedEntityOwnershipServiceTest extends AbstractClusterRefEntityOwnershipTest {
-    static final String ENTITY_TYPE = "test";
-    static final String ENTITY_TYPE2 = "test2";
-    static final QName QNAME = QName.create("test", "2015-08-11", "foo");
-    static int ID_COUNTER = 1;
-
-    private final String dataStoreName = "config" + ID_COUNTER++;
-    private AbstractDataStore dataStore;
-
-    @Before
-    public void setUp() {
-        DatastoreContext datastoreContext = DatastoreContext.newBuilder().dataStoreName(dataStoreName)
-                .shardInitializationTimeout(10, TimeUnit.SECONDS).build();
-
-        Configuration configuration = new ConfigurationImpl(new EmptyModuleShardConfigProvider()) {
-            @Override
-            public Collection<MemberName> getUniqueMemberNamesForAllShards() {
-                return Sets.newHashSet(MemberName.forName("member-1"));
-            }
-        };
-
-        DatastoreContextFactory mockContextFactory = mock(DatastoreContextFactory.class);
-        Mockito.doReturn(datastoreContext).when(mockContextFactory).getBaseDatastoreContext();
-        Mockito.doReturn(datastoreContext).when(mockContextFactory).getShardDatastoreContext(Mockito.anyString());
-
-        dataStore = new DistributedDataStore(getSystem(), new MockClusterWrapper(), configuration,
-                mockContextFactory, null);
-
-        dataStore.onModelContextUpdated(EOSTestUtils.SCHEMA_CONTEXT);
-    }
-
-    @After
-    public void tearDown() {
-        dataStore.close();
-    }
-
-    private static <T> T verifyMessage(final DistributedEntityOwnershipService mock, final Class<T> type) {
-        final ArgumentCaptor<T> message = ArgumentCaptor.forClass(type);
-        verify(mock).executeLocalEntityOwnershipShardOperation(message.capture());
-        return message.getValue();
-    }
-
-    @Test
-    public void testEntityOwnershipShardCreated() throws Exception {
-        DistributedEntityOwnershipService service = DistributedEntityOwnershipService.start(dataStore.getActorUtils(),
-                EntityOwnerSelectionStrategyConfig.newBuilder().build());
-
-        Future<ActorRef> future = dataStore.getActorUtils().findLocalShardAsync(
-                DistributedEntityOwnershipService.ENTITY_OWNERSHIP_SHARD_NAME);
-        ActorRef shardActor = Await.result(future, FiniteDuration.create(10, TimeUnit.SECONDS));
-        assertNotNull(DistributedEntityOwnershipService.ENTITY_OWNERSHIP_SHARD_NAME + " not found", shardActor);
-
-        service.close();
-    }
-
-    @Test
-    public void testRegisterCandidate() throws Exception {
-        DistributedEntityOwnershipService service = spy(DistributedEntityOwnershipService.start(
-            dataStore.getActorUtils(), EntityOwnerSelectionStrategyConfig.newBuilder().build()));
-
-        YangInstanceIdentifier entityId = YangInstanceIdentifier.of(QNAME);
-        DOMEntity entity = new DOMEntity(ENTITY_TYPE, entityId);
-
-        DOMEntityOwnershipCandidateRegistration reg = service.registerCandidate(entity);
-        verifyRegisterCandidateLocal(service, entity);
-        verifyEntityOwnershipCandidateRegistration(entity, reg);
-        verifyEntityCandidate(service.getLocalEntityOwnershipShard(), ENTITY_TYPE, entityId,
-                dataStore.getActorUtils().getCurrentMemberName().getName());
-
-        // Register the same entity - should throw exception
-
-        try {
-            service.registerCandidate(entity);
-            fail("Expected CandidateAlreadyRegisteredException");
-        } catch (CandidateAlreadyRegisteredException e) {
-            // expected
-            assertEquals("getEntity", entity, e.getEntity());
-        }
-
-        // Register a different entity - should succeed
-        reset(service);
-
-        DOMEntity entity2 = new DOMEntity(ENTITY_TYPE2, entityId);
-        DOMEntityOwnershipCandidateRegistration reg2 = service.registerCandidate(entity2);
-
-        verifyEntityOwnershipCandidateRegistration(entity2, reg2);
-        verifyEntityCandidate(service.getLocalEntityOwnershipShard(), ENTITY_TYPE2, entityId,
-                dataStore.getActorUtils().getCurrentMemberName().getName());
-
-        service.close();
-    }
-
-    @Test
-    public void testCloseCandidateRegistration() throws Exception {
-        DistributedEntityOwnershipService service = spy(DistributedEntityOwnershipService.start(
-            dataStore.getActorUtils(), EntityOwnerSelectionStrategyConfig.newBuilder().build()));
-
-        DOMEntity entity = new DOMEntity(ENTITY_TYPE, YangInstanceIdentifier.of(QNAME));
-
-        DOMEntityOwnershipCandidateRegistration reg = service.registerCandidate(entity);
-
-        verifyEntityOwnershipCandidateRegistration(entity, reg);
-        verifyRegisterCandidateLocal(service, entity);
-
-        reset(service);
-        reg.close();
-        UnregisterCandidateLocal unregCandidate = verifyMessage(service, UnregisterCandidateLocal.class);
-        assertEquals("getEntity", entity, unregCandidate.getEntity());
-
-        // Re-register - should succeed.
-        reset(service);
-        service.registerCandidate(entity);
-        verifyRegisterCandidateLocal(service, entity);
-
-        service.close();
-    }
-
-    @Test
-    public void testListenerRegistration() {
-        DistributedEntityOwnershipService service = spy(DistributedEntityOwnershipService.start(
-            dataStore.getActorUtils(), EntityOwnerSelectionStrategyConfig.newBuilder().build()));
-
-        YangInstanceIdentifier entityId = YangInstanceIdentifier.of(QNAME);
-        DOMEntity entity = new DOMEntity(ENTITY_TYPE, entityId);
-        DOMEntityOwnershipListener listener = mock(DOMEntityOwnershipListener.class);
-
-        DOMEntityOwnershipListenerRegistration reg = service.registerListener(entity.getType(), listener);
-
-        assertNotNull("EntityOwnershipListenerRegistration null", reg);
-        assertEquals("getEntityType", entity.getType(), reg.getEntityType());
-        assertEquals("getInstance", listener, reg.getInstance());
-
-        RegisterListenerLocal regListener = verifyMessage(service, RegisterListenerLocal.class);
-        assertSame("getListener", listener, regListener.getListener());
-        assertEquals("getEntityType", entity.getType(), regListener.getEntityType());
-
-        reset(service);
-        reg.close();
-        UnregisterListenerLocal unregListener = verifyMessage(service, UnregisterListenerLocal.class);
-        assertEquals("getEntityType", entity.getType(), unregListener.getEntityType());
-        assertSame("getListener", listener, unregListener.getListener());
-
-        service.close();
-    }
-
-    @Test
-    public void testGetOwnershipState() throws Exception {
-        DistributedEntityOwnershipService service = spy(DistributedEntityOwnershipService.start(
-            dataStore.getActorUtils(), EntityOwnerSelectionStrategyConfig.newBuilder().build()));
-
-        final Shard mockShard = Mockito.mock(Shard.class);
-        ShardDataTree shardDataTree = new ShardDataTree(mockShard, EOSTestUtils.SCHEMA_CONTEXT, TreeType.OPERATIONAL);
-
-        when(service.getLocalEntityOwnershipShardDataTree()).thenReturn(shardDataTree.getDataTree());
-
-        DOMEntity entity1 = new DOMEntity(ENTITY_TYPE, "one");
-        writeNode(ENTITY_OWNERS_PATH, entityOwnersWithCandidate(ENTITY_TYPE, entity1.getIdentifier(), "member-1"),
-                shardDataTree);
-        writeNode(ENTITY_OWNERS_PATH, entityOwnersWithEntityTypeEntry(entityTypeEntryWithEntityEntry(entity1.getType(),
-                entityEntryWithOwner(entity1.getIdentifier(), "member-1"))), shardDataTree);
-        verifyGetOwnershipState(service, entity1, EntityOwnershipState.IS_OWNER);
-
-        writeNode(ENTITY_OWNERS_PATH, entityOwnersWithCandidate(ENTITY_TYPE,
-                entity1.getIdentifier(), "member-2"), shardDataTree);
-        writeNode(entityPath(entity1.getType(), entity1.getIdentifier()),
-                entityEntryWithOwner(entity1.getIdentifier(), "member-2"), shardDataTree);
-        verifyGetOwnershipState(service, entity1, EntityOwnershipState.OWNED_BY_OTHER);
-
-        writeNode(entityPath(entity1.getType(), entity1.getIdentifier()), entityEntryWithOwner(entity1.getIdentifier(),
-                ""), shardDataTree);
-        verifyGetOwnershipState(service, entity1, EntityOwnershipState.NO_OWNER);
-
-        DOMEntity entity2 = new DOMEntity(ENTITY_TYPE, "two");
-        Optional<EntityOwnershipState> state = service.getOwnershipState(entity2);
-        assertFalse("getOwnershipState present", state.isPresent());
-
-        writeNode(ENTITY_OWNERS_PATH, entityOwnersWithCandidate(ENTITY_TYPE, entity2.getIdentifier(), "member-1"),
-                shardDataTree);
-        writeNode(entityPath(entity2.getType(), entity2.getIdentifier()), ImmutableNodes.mapEntry(ENTITY_QNAME,
-                ENTITY_ID_QNAME, entity2.getIdentifier()), shardDataTree);
-        verifyGetOwnershipState(service, entity2, EntityOwnershipState.NO_OWNER);
-
-        deleteNode(candidatePath(entityPath(entity2.getType(), entity2.getIdentifier()), "member-1"), shardDataTree);
-        Optional<EntityOwnershipState> state2 = service.getOwnershipState(entity2);
-        assertFalse("getOwnershipState present", state2.isPresent());
-        service.close();
-    }
-
-    @Test
-    public void testIsCandidateRegistered() throws CandidateAlreadyRegisteredException {
-        DistributedEntityOwnershipService service = DistributedEntityOwnershipService.start(dataStore.getActorUtils(),
-                EntityOwnerSelectionStrategyConfig.newBuilder().build());
-
-        final DOMEntity test = new DOMEntity("test-type", "test");
-
-        assertFalse(service.isCandidateRegistered(test));
-
-        service.registerCandidate(test);
-
-        assertTrue(service.isCandidateRegistered(test));
-
-        service.close();
-    }
-
-    private static void verifyGetOwnershipState(final DistributedEntityOwnershipService service, final DOMEntity entity,
-            final EntityOwnershipState expState) {
-        Optional<EntityOwnershipState> state = service.getOwnershipState(entity);
-        assertTrue("getOwnershipState present", state.isPresent());
-        assertEquals("EntityOwnershipState", expState, state.get());
-    }
-
-    @SuppressWarnings("checkstyle:IllegalCatch")
-    private void verifyEntityCandidate(final ActorRef entityOwnershipShard, final String entityType,
-            final YangInstanceIdentifier entityId, final String candidateName) {
-        verifyEntityCandidate(entityType, entityId, candidateName, path -> {
-            try {
-                return dataStore.newReadOnlyTransaction().read(path).get(5, TimeUnit.SECONDS).get();
-            } catch (Exception e) {
-                return null;
-            }
-        });
-    }
-
-    private static void verifyRegisterCandidateLocal(final DistributedEntityOwnershipService service,
-            final DOMEntity entity) {
-        RegisterCandidateLocal regCandidate = verifyMessage(service, RegisterCandidateLocal.class);
-        assertEquals("getEntity", entity, regCandidate.getEntity());
-    }
-
-    private static void verifyEntityOwnershipCandidateRegistration(final DOMEntity entity,
-            final DOMEntityOwnershipCandidateRegistration reg) {
-        assertNotNull("EntityOwnershipCandidateRegistration null", reg);
-        assertEquals("getInstance", entity, reg.getInstance());
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/EOSTestUtils.java b/opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/EOSTestUtils.java
deleted file mode 100644 (file)
index dda3404..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (c) 2019 PANTHEON.tech, s.r.o. 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.entityownership;
-
-import java.io.File;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
-
-final class EOSTestUtils {
-    static final EffectiveModelContext SCHEMA_CONTEXT = YangParserTestUtils.parseYangFiles(
-        new File("src/main/yang/entity-owners.yang"));
-
-    private EOSTestUtils() {
-        // Hidden on purpose
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/EntityOwnerChangeListenerTest.java b/opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/EntityOwnerChangeListenerTest.java
deleted file mode 100644 (file)
index 6eb5847..0000000
+++ /dev/null
@@ -1,143 +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.entityownership;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.ENTITY_OWNERS_PATH;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.entityEntryWithOwner;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.entityOwnersWithCandidate;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.entityPath;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.opendaylight.controller.cluster.access.concepts.MemberName;
-import org.opendaylight.controller.cluster.datastore.Shard;
-import org.opendaylight.controller.cluster.datastore.ShardDataTree;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntity;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.TreeType;
-
-/**
- * Unit tests for EntityOwnerChangeListener.
- *
- * @author Thomas Pantelis
- */
-public class EntityOwnerChangeListenerTest {
-    private static final String LOCAL_MEMBER_NAME = "member-1";
-    private static final String REMOTE_MEMBER_NAME1 = "member-2";
-    private static final String REMOTE_MEMBER_NAME2 = "member-3";
-    private static final String ENTITY_TYPE = "test";
-    private static final YangInstanceIdentifier ENTITY_ID1 =
-            YangInstanceIdentifier.of(QName.create("test", "2015-08-14", "entity1"));
-    private static final YangInstanceIdentifier ENTITY_ID2 =
-            YangInstanceIdentifier.of(QName.create("test", "2015-08-14", "entity2"));
-    private static final DOMEntity ENTITY1 = new DOMEntity(ENTITY_TYPE, ENTITY_ID1);
-    private static final DOMEntity ENTITY2 = new DOMEntity(ENTITY_TYPE, ENTITY_ID2);
-
-    private final Shard mockShard = Mockito.mock(Shard.class);
-
-    private final ShardDataTree shardDataTree = new ShardDataTree(mockShard, EOSTestUtils.SCHEMA_CONTEXT,
-        TreeType.OPERATIONAL);
-    private final EntityOwnershipListenerSupport mockListenerSupport = mock(EntityOwnershipListenerSupport.class);
-    private EntityOwnerChangeListener listener;
-
-    @Before
-    public void setup() {
-        listener = new EntityOwnerChangeListener(MemberName.forName(LOCAL_MEMBER_NAME), mockListenerSupport);
-        listener.init(shardDataTree);
-    }
-
-    @Test
-    public void testOnDataTreeChanged() throws Exception {
-        writeNode(ENTITY_OWNERS_PATH, entityOwnersWithCandidate(ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME));
-        writeNode(ENTITY_OWNERS_PATH, entityOwnersWithCandidate(ENTITY_TYPE, ENTITY_ID2, LOCAL_MEMBER_NAME));
-        verify(mockListenerSupport, never()).notifyEntityOwnershipListeners(any(DOMEntity.class), anyBoolean(),
-                anyBoolean(), anyBoolean());
-
-        // Write local member as owner for entity 1
-
-        writeNode(entityPath(ENTITY_TYPE, ENTITY_ID1), entityEntryWithOwner(ENTITY_ID1, LOCAL_MEMBER_NAME));
-        verify(mockListenerSupport).notifyEntityOwnershipListeners(ENTITY1, false, true, true);
-
-        // Add remote member 1 as candidate for entity 1 - listener support should not get notified
-
-        reset(mockListenerSupport);
-        writeNode(ENTITY_OWNERS_PATH, entityOwnersWithCandidate(ENTITY_TYPE, ENTITY_ID1, REMOTE_MEMBER_NAME1));
-        verify(mockListenerSupport, never()).notifyEntityOwnershipListeners(any(DOMEntity.class), anyBoolean(),
-                anyBoolean(), anyBoolean());
-
-        // Change owner to remote member 1 for entity 1
-
-        reset(mockListenerSupport);
-        writeNode(entityPath(ENTITY_TYPE, ENTITY_ID1), entityEntryWithOwner(ENTITY_ID1, REMOTE_MEMBER_NAME1));
-        verify(mockListenerSupport).notifyEntityOwnershipListeners(ENTITY1, true, false, true);
-
-        // Change owner to remote member 2 for entity 1
-
-        reset(mockListenerSupport);
-        writeNode(entityPath(ENTITY_TYPE, ENTITY_ID1), entityEntryWithOwner(ENTITY_ID1, REMOTE_MEMBER_NAME2));
-        verify(mockListenerSupport).notifyEntityOwnershipListeners(ENTITY1, false, false, true);
-
-        // Clear the owner for entity 1
-
-        reset(mockListenerSupport);
-        writeNode(entityPath(ENTITY_TYPE, ENTITY_ID1), entityEntryWithOwner(ENTITY_ID1, ""));
-        verify(mockListenerSupport).notifyEntityOwnershipListeners(ENTITY1, false, false, false);
-
-        // Change owner to the local member for entity 1
-
-        writeNode(entityPath(ENTITY_TYPE, ENTITY_ID1), entityEntryWithOwner(ENTITY_ID1, LOCAL_MEMBER_NAME));
-        verify(mockListenerSupport).notifyEntityOwnershipListeners(ENTITY1, false, true, true);
-
-        // Change owner to remote member 2 for entity 2
-
-        reset(mockListenerSupport);
-        writeNode(entityPath(ENTITY_TYPE, ENTITY_ID2), entityEntryWithOwner(ENTITY_ID2, REMOTE_MEMBER_NAME1));
-        verify(mockListenerSupport).notifyEntityOwnershipListeners(ENTITY2, false, false, true);
-
-        // Change owner to the local member for entity 2
-
-        reset(mockListenerSupport);
-        writeNode(entityPath(ENTITY_TYPE, ENTITY_ID2), entityEntryWithOwner(ENTITY_ID2, LOCAL_MEMBER_NAME));
-        verify(mockListenerSupport).notifyEntityOwnershipListeners(ENTITY2, false, true, true);
-
-        // Write local member owner for entity 2 again - expect no change
-
-        reset(mockListenerSupport);
-        writeNode(entityPath(ENTITY_TYPE, ENTITY_ID2), entityEntryWithOwner(ENTITY_ID2, LOCAL_MEMBER_NAME));
-        verify(mockListenerSupport, never()).notifyEntityOwnershipListeners(any(DOMEntity.class), anyBoolean(),
-                anyBoolean(), anyBoolean());
-
-        // Clear the owner for entity 2
-
-        reset(mockListenerSupport);
-        writeNode(entityPath(ENTITY_TYPE, ENTITY_ID2), entityEntryWithOwner(ENTITY_ID2, null));
-        verify(mockListenerSupport).notifyEntityOwnershipListeners(ENTITY2, true, false, false);
-
-        // Clear the owner for entity 2 again - expect no change
-
-        reset(mockListenerSupport);
-        writeNode(entityPath(ENTITY_TYPE, ENTITY_ID2), entityEntryWithOwner(ENTITY_ID2, null));
-        verify(mockListenerSupport, never()).notifyEntityOwnershipListeners(any(DOMEntity.class), anyBoolean(),
-                anyBoolean(), anyBoolean());
-    }
-
-    private void writeNode(final YangInstanceIdentifier path, final NormalizedNode node)
-            throws DataValidationFailedException {
-        AbstractEntityOwnershipTest.writeNode(path, node, shardDataTree);
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/EntityOwnershipListenerActorTest.java b/opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/EntityOwnershipListenerActorTest.java
deleted file mode 100644 (file)
index 7b14e73..0000000
+++ /dev/null
@@ -1,78 +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.entityownership;
-
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.verify;
-
-import akka.actor.ActorRef;
-import akka.testkit.TestActorRef;
-import org.junit.After;
-import org.junit.Test;
-import org.opendaylight.controller.cluster.raft.TestActorFactory;
-import org.opendaylight.mdsal.eos.common.api.EntityOwnershipChangeState;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntity;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipChange;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipListener;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-
-/**
- * Unit tests for EntityOwnershipListenerActor.
- *
- * @author Thomas Pantelis
- */
-public class EntityOwnershipListenerActorTest extends AbstractEntityOwnershipTest {
-    private final TestActorFactory actorFactory = new TestActorFactory(getSystem());
-
-    @After
-    public void tearDown() {
-        actorFactory.close();
-    }
-
-    @Test
-    public void testOnEntityOwnershipChanged() {
-        DOMEntityOwnershipListener mockListener = mock(DOMEntityOwnershipListener.class);
-
-        TestActorRef<EntityOwnershipListenerActor> listenerActor = actorFactory.createTestActor(
-                EntityOwnershipListenerActor.props(mockListener), actorFactory.generateActorId("listener"));
-
-        DOMEntity entity = new DOMEntity("test", YangInstanceIdentifier.of(QName.create("test", "id1")));
-        boolean wasOwner = false;
-        boolean isOwner = true;
-        boolean hasOwner = true;
-        listenerActor.tell(new DOMEntityOwnershipChange(entity, EntityOwnershipChangeState.from(
-                wasOwner, isOwner, hasOwner)), ActorRef.noSender());
-
-        verify(mockListener, timeout(5000)).ownershipChanged(ownershipChange(entity, wasOwner, isOwner, hasOwner));
-    }
-
-    @Test
-    public void testOnEntityOwnershipChangedWithListenerEx() {
-        DOMEntityOwnershipListener mockListener = mock(DOMEntityOwnershipListener.class);
-
-        DOMEntity entity1 = new DOMEntity("test", YangInstanceIdentifier.of(QName.create("test", "id1")));
-        doThrow(new RuntimeException("mock")).when(mockListener).ownershipChanged(
-                ownershipChange(entity1, false, true, true));
-        DOMEntity entity2 = new DOMEntity("test", YangInstanceIdentifier.of(QName.create("test", "id2")));
-        doNothing().when(mockListener).ownershipChanged(ownershipChange(entity2, true, false, false));
-
-        TestActorRef<EntityOwnershipListenerActor> listenerActor = actorFactory.createTestActor(
-                EntityOwnershipListenerActor.props(mockListener), actorFactory.generateActorId("listener"));
-
-        listenerActor.tell(new DOMEntityOwnershipChange(entity1, EntityOwnershipChangeState.from(
-                false, true, true)), ActorRef.noSender());
-        listenerActor.tell(new DOMEntityOwnershipChange(entity2, EntityOwnershipChangeState.from(
-                true, false, false)), ActorRef.noSender());
-
-        verify(mockListener, timeout(5000)).ownershipChanged(ownershipChange(entity2, true, false, false));
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/EntityOwnershipListenerSupportTest.java b/opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/EntityOwnershipListenerSupportTest.java
deleted file mode 100644 (file)
index 00fb6fa..0000000
+++ /dev/null
@@ -1,164 +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.entityownership;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.verify;
-
-import akka.actor.ActorContext;
-import akka.actor.ActorRef;
-import akka.actor.Props;
-import akka.testkit.TestActorRef;
-import akka.testkit.javadsl.TestKit;
-import com.google.common.util.concurrent.Uninterruptibles;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.cluster.raft.TestActorFactory;
-import org.opendaylight.controller.cluster.raft.utils.DoNothingActor;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntity;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipChange;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipListener;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import scala.collection.Iterator;
-import scala.collection.immutable.Iterable;
-
-/**
- * Unit tests for EntityOwnershipListenerSupport.
- *
- * @author Thomas Pantelis
- */
-public class EntityOwnershipListenerSupportTest extends AbstractEntityOwnershipTest {
-    private final TestActorFactory actorFactory = new TestActorFactory(getSystem());
-    private ActorContext actorContext;
-
-    @Before
-    public void setup() {
-        TestActorRef<DoNothingActor> actor = actorFactory.createTestActor(
-                Props.create(DoNothingActor.class), actorFactory.generateActorId("test"));
-
-        actorContext = actor.underlyingActor().getContext();
-    }
-
-    @After
-    public void tearDown() {
-        actorFactory.close();
-    }
-
-    @Test
-    public void testNotifyEntityOwnershipListeners() {
-        EntityOwnershipListenerSupport support = new EntityOwnershipListenerSupport(actorContext, "test");
-
-        DOMEntityOwnershipListener mockListener1 = mock(DOMEntityOwnershipListener.class, "EntityOwnershipListener1");
-        DOMEntityOwnershipListener mockListener2 = mock(DOMEntityOwnershipListener.class, "EntityOwnershipListener2");
-        DOMEntityOwnershipListener mockListener12 = mock(DOMEntityOwnershipListener.class,
-                "EntityOwnershipListener1_2");
-        String entityType1 = "type1";
-        String entityType2 = "type2";
-        final DOMEntity entity1 = new DOMEntity(entityType1, YangInstanceIdentifier.of(QName.create("test", "id1")));
-        final DOMEntity entity2 = new DOMEntity(entityType2, YangInstanceIdentifier.of(QName.create("test", "id2")));
-        final DOMEntity entity3 = new DOMEntity("noListener", YangInstanceIdentifier.of(QName.create("test", "id5")));
-
-        // Add EntityOwnershipListener registrations.
-
-        support.addEntityOwnershipListener(entityType1, mockListener1);
-        support.addEntityOwnershipListener(entityType1, mockListener1); // register again - should be noop
-        support.addEntityOwnershipListener(entityType1, mockListener12);
-        support.addEntityOwnershipListener(entityType2, mockListener2);
-
-        // Notify entity1 changed and verify appropriate listeners are notified.
-
-        support.notifyEntityOwnershipListeners(entity1, false, true, true);
-
-        verify(mockListener1, timeout(5000)).ownershipChanged(ownershipChange(entity1, false, true, true));
-        verify(mockListener12, timeout(5000)).ownershipChanged(ownershipChange(entity1, false, true, true));
-        Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
-        verify(mockListener2, never()).ownershipChanged(any(DOMEntityOwnershipChange.class));
-        assertEquals("# of listener actors", 2, actorContext.children().size());
-        reset(mockListener1, mockListener2, mockListener12);
-
-        // Notify entity2 changed and verify appropriate listeners are notified.
-
-        support.notifyEntityOwnershipListeners(entity2, false, true, true);
-
-        verify(mockListener2, timeout(5000)).ownershipChanged(ownershipChange(entity2, false, true, true));
-        Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
-        verify(mockListener1, never()).ownershipChanged(any(DOMEntityOwnershipChange.class));
-        verify(mockListener12, never()).ownershipChanged(any(DOMEntityOwnershipChange.class));
-        assertEquals("# of listener actors", 3, actorContext.children().size());
-        reset(mockListener1, mockListener2, mockListener12);
-
-        // Notify entity3 changed and verify no listeners are notified.
-
-        support.notifyEntityOwnershipListeners(entity3, true, false, true);
-
-        Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
-        verify(mockListener1, never()).ownershipChanged(any(DOMEntityOwnershipChange.class));
-        verify(mockListener2, never()).ownershipChanged(any(DOMEntityOwnershipChange.class));
-        verify(mockListener12, never()).ownershipChanged(any(DOMEntityOwnershipChange.class));
-        reset(mockListener1, mockListener2, mockListener12);
-
-        Iterable<ActorRef> listenerActors = actorContext.children();
-        assertEquals("# of listener actors", 3, listenerActors.size());
-
-        // Unregister mockListener1, issue a change for entity1 and verify only remaining listeners are notified.
-
-        support.removeEntityOwnershipListener(entityType1, mockListener1);
-        support.notifyEntityOwnershipListeners(entity1, true, false, true);
-
-        verify(mockListener12, timeout(5000)).ownershipChanged(ownershipChange(entity1, true, false, true));
-        Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
-        verify(mockListener1, never()).ownershipChanged(any(DOMEntityOwnershipChange.class));
-        reset(mockListener1, mockListener2, mockListener12);
-
-        // Unregister all listeners and verify their listener actors are destroyed.
-
-        List<TestKit> watchers = new ArrayList<>();
-        for (Iterator<ActorRef> iter = listenerActors.iterator(); iter.hasNext();) {
-            TestKit kit = new TestKit(getSystem());
-            kit.watch(iter.next());
-            watchers.add(kit);
-        }
-
-        support.removeEntityOwnershipListener(entityType1, mockListener12);
-        support.removeEntityOwnershipListener(entityType1, mockListener12); // un-register again - should be noop
-        support.removeEntityOwnershipListener(entityType2, mockListener2);
-
-        Iterator<ActorRef> iter = listenerActors.iterator();
-        for (TestKit kit: watchers) {
-            kit.expectTerminated(kit.duration("3 seconds"), iter.next());
-        }
-
-        assertEquals("# of listener actors", 0, actorContext.children().size());
-
-        // Re-register mockListener1 and verify it is notified.
-
-        reset(mockListener1, mockListener2);
-
-        support.addEntityOwnershipListener(entityType1, mockListener1);
-        support.notifyEntityOwnershipListeners(entity1, false, false, true);
-
-        verify(mockListener1, timeout(5000)).ownershipChanged(ownershipChange(entity1, false, false, true));
-        verify(mockListener12, never()).ownershipChanged(any(DOMEntityOwnershipChange.class));
-        verify(mockListener2, never()).ownershipChanged(any(DOMEntityOwnershipChange.class));
-
-        // Quickly register and unregister mockListener2 - expecting no exceptions.
-
-        support.addEntityOwnershipListener(entityType1, mockListener2);
-        support.removeEntityOwnershipListener(entityType1, mockListener2);
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/EntityOwnershipShardTest.java b/opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/EntityOwnershipShardTest.java
deleted file mode 100644 (file)
index 000ad3b..0000000
+++ /dev/null
@@ -1,1310 +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.entityownership;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.AdditionalMatchers.or;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor.clearMessages;
-import static org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor.expectFirstMatching;
-import static org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor.expectMatching;
-
-import akka.actor.ActorRef;
-import akka.actor.PoisonPill;
-import akka.actor.Props;
-import akka.actor.Terminated;
-import akka.dispatch.Dispatchers;
-import akka.testkit.TestActorRef;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.util.concurrent.Uninterruptibles;
-import java.time.Duration;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.function.Predicate;
-import org.junit.After;
-import org.junit.Test;
-import org.opendaylight.controller.cluster.access.concepts.MemberName;
-import org.opendaylight.controller.cluster.datastore.DatastoreContext;
-import org.opendaylight.controller.cluster.datastore.DatastoreContext.Builder;
-import org.opendaylight.controller.cluster.datastore.ShardTestKit;
-import org.opendaylight.controller.cluster.datastore.identifiers.ShardIdentifier;
-import org.opendaylight.controller.cluster.datastore.messages.BatchedModifications;
-import org.opendaylight.controller.cluster.datastore.messages.PeerAddressResolved;
-import org.opendaylight.controller.cluster.datastore.messages.PeerDown;
-import org.opendaylight.controller.cluster.datastore.messages.PeerUp;
-import org.opendaylight.controller.cluster.datastore.messages.SuccessReply;
-import org.opendaylight.controller.cluster.entityownership.messages.CandidateAdded;
-import org.opendaylight.controller.cluster.entityownership.messages.RegisterCandidateLocal;
-import org.opendaylight.controller.cluster.entityownership.messages.RegisterListenerLocal;
-import org.opendaylight.controller.cluster.entityownership.messages.UnregisterCandidateLocal;
-import org.opendaylight.controller.cluster.entityownership.messages.UnregisterListenerLocal;
-import org.opendaylight.controller.cluster.entityownership.selectionstrategy.EntityOwnerSelectionStrategyConfig;
-import org.opendaylight.controller.cluster.entityownership.selectionstrategy.LastCandidateSelectionStrategy;
-import org.opendaylight.controller.cluster.raft.RaftState;
-import org.opendaylight.controller.cluster.raft.TestActorFactory;
-import org.opendaylight.controller.cluster.raft.base.messages.ElectionTimeout;
-import org.opendaylight.controller.cluster.raft.base.messages.TimeoutNow;
-import org.opendaylight.controller.cluster.raft.messages.AppendEntries;
-import org.opendaylight.controller.cluster.raft.messages.RequestVote;
-import org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntity;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipChange;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipListener;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-
-/**
- * Unit tests for EntityOwnershipShard.
- *
- * @author Thomas Pantelis
- */
-public class EntityOwnershipShardTest extends AbstractEntityOwnershipTest {
-    private static final String ENTITY_TYPE = "test type";
-    private static final YangInstanceIdentifier ENTITY_ID1 =
-            YangInstanceIdentifier.of(QName.create("test", "2015-08-14", "entity1"));
-    private static final YangInstanceIdentifier ENTITY_ID2 =
-            YangInstanceIdentifier.of(QName.create("test", "2015-08-14", "entity2"));
-    private static final YangInstanceIdentifier ENTITY_ID3 =
-            YangInstanceIdentifier.of(QName.create("test", "2015-08-14", "entity3"));
-    private static final YangInstanceIdentifier ENTITY_ID4 =
-            YangInstanceIdentifier.of(QName.create("test", "2015-08-14", "entity4"));
-    private static final YangInstanceIdentifier ENTITY_ID5 =
-            YangInstanceIdentifier.of(QName.create("test", "2015-08-14", "entity5"));
-    private static final String LOCAL_MEMBER_NAME = "local-member-1";
-    private static final String PEER_MEMBER_1_NAME = "peer-member-1";
-    private static final String PEER_MEMBER_2_NAME = "peer-member-2";
-
-    private Builder dataStoreContextBuilder = DatastoreContext.newBuilder().persistent(false);
-    private final TestActorFactory actorFactory = new TestActorFactory(getSystem());
-
-    @After
-    public void tearDown() {
-        actorFactory.close();
-    }
-
-    @Test
-    public void testOnRegisterCandidateLocal() {
-        testLog.info("testOnRegisterCandidateLocal starting");
-
-        ShardTestKit kit = new ShardTestKit(getSystem());
-
-        TestActorRef<EntityOwnershipShard> shard = actorFactory.createTestActor(newLocalShardProps());
-
-        ShardTestKit.waitUntilLeader(shard);
-
-        YangInstanceIdentifier entityId = ENTITY_ID1;
-        DOMEntity entity = new DOMEntity(ENTITY_TYPE, entityId);
-
-        shard.tell(new RegisterCandidateLocal(entity), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        verifyCommittedEntityCandidate(shard, ENTITY_TYPE, entityId, LOCAL_MEMBER_NAME);
-        verifyOwner(shard, ENTITY_TYPE, entityId, LOCAL_MEMBER_NAME);
-
-        testLog.info("testOnRegisterCandidateLocal ending");
-    }
-
-    @Test
-    public void testOnRegisterCandidateLocalWithNoInitialLeader() {
-        testLog.info("testOnRegisterCandidateLocalWithNoInitialLeader starting");
-
-        final ShardTestKit kit = new ShardTestKit(getSystem());
-
-        dataStoreContextBuilder.shardHeartbeatIntervalInMillis(100).shardElectionTimeoutFactor(2);
-
-        ShardIdentifier leaderId = newShardId(LOCAL_MEMBER_NAME);
-        ShardIdentifier peerId = newShardId(PEER_MEMBER_1_NAME);
-
-        TestActorRef<TestEntityOwnershipShard> peer = actorFactory.createTestActor(TestEntityOwnershipShard.props(
-                newShardBuilder(peerId, peerMap(leaderId.toString()), PEER_MEMBER_1_NAME)), peerId.toString());
-        TestEntityOwnershipShard peerShard = peer.underlyingActor();
-        peerShard.startDroppingMessagesOfType(RequestVote.class);
-        peerShard.startDroppingMessagesOfType(ElectionTimeout.class);
-
-        TestActorRef<EntityOwnershipShard> shard = actorFactory.createTestActor(
-                newShardProps(leaderId, peerMap(peerId.toString()), LOCAL_MEMBER_NAME), leaderId.toString());
-
-        YangInstanceIdentifier entityId = ENTITY_ID1;
-        DOMEntity entity = new DOMEntity(ENTITY_TYPE, entityId);
-
-        shard.tell(new RegisterCandidateLocal(entity), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        // Now allow RequestVotes to the peer so the shard becomes the leader. This should retry the commit.
-        peerShard.stopDroppingMessagesOfType(RequestVote.class);
-
-        verifyCommittedEntityCandidate(shard, ENTITY_TYPE, entityId, LOCAL_MEMBER_NAME);
-        verifyOwner(shard, ENTITY_TYPE, entityId, LOCAL_MEMBER_NAME);
-
-        testLog.info("testOnRegisterCandidateLocalWithNoInitialLeader ending");
-    }
-
-    @Test
-    public void testOnRegisterCandidateLocalWithNoInitialConsensus() {
-        testLog.info("testOnRegisterCandidateLocalWithNoInitialConsensus starting");
-
-        final ShardTestKit kit = new ShardTestKit(getSystem());
-
-        dataStoreContextBuilder.shardHeartbeatIntervalInMillis(100).shardElectionTimeoutFactor(2)
-                .shardTransactionCommitTimeoutInSeconds(1);
-
-        ShardIdentifier leaderId = newShardId(LOCAL_MEMBER_NAME);
-        ShardIdentifier peerId = newShardId(PEER_MEMBER_1_NAME);
-
-        TestActorRef<TestEntityOwnershipShard> peer = actorFactory.createTestActor(TestEntityOwnershipShard.props(
-                newShardBuilder(peerId, peerMap(leaderId.toString()), PEER_MEMBER_1_NAME)), peerId.toString());
-        TestEntityOwnershipShard peerShard = peer.underlyingActor();
-        peerShard.startDroppingMessagesOfType(ElectionTimeout.class);
-
-        // Drop AppendEntries so consensus isn't reached.
-        peerShard.startDroppingMessagesOfType(AppendEntries.class);
-
-        TestActorRef<EntityOwnershipShard> leader = actorFactory.createTestActor(
-                newShardProps(leaderId, peerMap(peerId.toString()), LOCAL_MEMBER_NAME), leaderId.toString());
-
-        ShardTestKit.waitUntilLeader(leader);
-
-        YangInstanceIdentifier entityId = ENTITY_ID1;
-        DOMEntity entity = new DOMEntity(ENTITY_TYPE, entityId);
-
-        leader.tell(new RegisterCandidateLocal(entity), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        // Wait enough time for the commit to timeout.
-        Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS);
-
-        // Resume AppendEntries - the follower should ack the commit which should then result in the candidate
-        // write being applied to the state.
-        peerShard.stopDroppingMessagesOfType(AppendEntries.class);
-
-        verifyCommittedEntityCandidate(leader, ENTITY_TYPE, entityId, LOCAL_MEMBER_NAME);
-        verifyOwner(leader, ENTITY_TYPE, entityId, LOCAL_MEMBER_NAME);
-
-        testLog.info("testOnRegisterCandidateLocalWithNoInitialConsensus ending");
-    }
-
-    @Test
-    public void testOnRegisterCandidateLocalWithIsolatedLeader() throws Exception {
-        testLog.info("testOnRegisterCandidateLocalWithIsolatedLeader starting");
-
-        final ShardTestKit kit = new ShardTestKit(getSystem());
-
-        dataStoreContextBuilder.shardHeartbeatIntervalInMillis(100).shardElectionTimeoutFactor(2)
-                .shardIsolatedLeaderCheckIntervalInMillis(50);
-
-        ShardIdentifier leaderId = newShardId(LOCAL_MEMBER_NAME);
-        ShardIdentifier peerId = newShardId(PEER_MEMBER_1_NAME);
-
-        TestActorRef<TestEntityOwnershipShard> peer = actorFactory.createTestActor(TestEntityOwnershipShard.props(
-                newShardBuilder(peerId, peerMap(leaderId.toString()), PEER_MEMBER_1_NAME)), peerId.toString());
-        TestEntityOwnershipShard peerShard = peer.underlyingActor();
-        peerShard.startDroppingMessagesOfType(ElectionTimeout.class);
-
-        TestActorRef<EntityOwnershipShard> leader = actorFactory.createTestActor(
-                newShardProps(leaderId, peerMap(peerId.toString()), LOCAL_MEMBER_NAME));
-
-        ShardTestKit.waitUntilLeader(leader);
-
-        // Drop AppendEntries and wait enough time for the shard to switch to IsolatedLeader.
-        peerShard.startDroppingMessagesOfType(AppendEntries.class);
-        verifyRaftState(leader, state ->
-                assertEquals("getRaftState", RaftState.IsolatedLeader.toString(), state.getRaftState()));
-
-        YangInstanceIdentifier entityId = ENTITY_ID1;
-        DOMEntity entity = new DOMEntity(ENTITY_TYPE, entityId);
-
-        leader.tell(new RegisterCandidateLocal(entity), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        // Resume AppendEntries - the candidate write should now be committed.
-        peerShard.stopDroppingMessagesOfType(AppendEntries.class);
-        verifyCommittedEntityCandidate(leader, ENTITY_TYPE, entityId, LOCAL_MEMBER_NAME);
-        verifyOwner(leader, ENTITY_TYPE, entityId, LOCAL_MEMBER_NAME);
-
-        testLog.info("testOnRegisterCandidateLocalWithIsolatedLeader ending");
-    }
-
-    @Test
-    public void testOnRegisterCandidateLocalWithRemoteLeader() {
-        testLog.info("testOnRegisterCandidateLocalWithRemoteLeader starting");
-
-        ShardTestKit kit = new ShardTestKit(getSystem());
-
-        dataStoreContextBuilder.shardHeartbeatIntervalInMillis(100).shardElectionTimeoutFactor(2)
-                .shardBatchedModificationCount(5);
-
-        ShardIdentifier leaderId = newShardId(PEER_MEMBER_1_NAME);
-        ShardIdentifier localId = newShardId(LOCAL_MEMBER_NAME);
-        TestActorRef<TestEntityOwnershipShard> leader = actorFactory.createTestActor(TestEntityOwnershipShard.props(
-                newShardBuilder(leaderId, peerMap(localId.toString()), PEER_MEMBER_1_NAME),
-                actorFactory.createActor(MessageCollectorActor.props())), leaderId.toString());
-        final TestEntityOwnershipShard leaderShard = leader.underlyingActor();
-
-        TestActorRef<TestEntityOwnershipShard> local = actorFactory.createTestActor(TestEntityOwnershipShard.props(
-                newShardBuilder(localId, peerMap(leaderId.toString()),LOCAL_MEMBER_NAME)), localId.toString());
-        local.underlyingActor().startDroppingMessagesOfType(ElectionTimeout.class);
-
-        local.tell(new RegisterCandidateLocal(new DOMEntity(ENTITY_TYPE, ENTITY_ID1)), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
-        verifyOwner(leader, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
-
-        // Test with initial commit timeout and subsequent retry.
-
-        local.tell(dataStoreContextBuilder.shardTransactionCommitTimeoutInSeconds(1).build(), ActorRef.noSender());
-        leaderShard.startDroppingMessagesOfType(BatchedModifications.class);
-
-        local.tell(new RegisterCandidateLocal(new DOMEntity(ENTITY_TYPE, ENTITY_ID2)), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        expectFirstMatching(leaderShard.collectorActor(), BatchedModifications.class);
-
-        // Send a bunch of registration messages quickly and verify.
-
-        leaderShard.stopDroppingMessagesOfType(BatchedModifications.class);
-        clearMessages(leaderShard.collectorActor());
-
-        int max = 100;
-        List<YangInstanceIdentifier> entityIds = new ArrayList<>();
-        for (int i = 1; i <= max; i++) {
-            YangInstanceIdentifier id = YangInstanceIdentifier.of(QName.create("test", "2015-08-14", "test" + i));
-            entityIds.add(id);
-            local.tell(new RegisterCandidateLocal(new DOMEntity(ENTITY_TYPE, id)), kit.getRef());
-        }
-
-        for (int i = 0; i < max; i++) {
-            verifyCommittedEntityCandidate(local, ENTITY_TYPE, entityIds.get(i), LOCAL_MEMBER_NAME);
-        }
-
-        testLog.info("testOnRegisterCandidateLocalWithRemoteLeader ending");
-    }
-
-    @Test
-    public void testOnUnregisterCandidateLocal() {
-        testLog.info("testOnUnregisterCandidateLocal starting");
-
-        ShardTestKit kit = new ShardTestKit(getSystem());
-        TestActorRef<EntityOwnershipShard> shard = actorFactory.createTestActor(newLocalShardProps());
-        ShardTestKit.waitUntilLeader(shard);
-
-        DOMEntity entity = new DOMEntity(ENTITY_TYPE, ENTITY_ID1);
-
-        // Register
-
-        shard.tell(new RegisterCandidateLocal(entity), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        verifyCommittedEntityCandidate(shard, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
-        verifyOwner(shard, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
-
-        // Unregister
-
-        shard.tell(new UnregisterCandidateLocal(entity), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        verifyOwner(shard, ENTITY_TYPE, ENTITY_ID1, "");
-
-        // Register again
-
-        shard.tell(new RegisterCandidateLocal(entity), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        verifyCommittedEntityCandidate(shard, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
-        verifyOwner(shard, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
-
-        testLog.info("testOnUnregisterCandidateLocal ending");
-    }
-
-    @Test
-    public void testOwnershipChanges() {
-        testLog.info("testOwnershipChanges starting");
-
-        final ShardTestKit kit = new ShardTestKit(getSystem());
-
-        dataStoreContextBuilder.shardHeartbeatIntervalInMillis(100).shardElectionTimeoutFactor(2);
-
-        ShardIdentifier leaderId = newShardId(LOCAL_MEMBER_NAME);
-        ShardIdentifier peerId1 = newShardId(PEER_MEMBER_1_NAME);
-        ShardIdentifier peerId2 = newShardId(PEER_MEMBER_2_NAME);
-
-        TestActorRef<TestEntityOwnershipShard> peer1 = actorFactory.createTestActor(TestEntityOwnershipShard.props(
-                newShardBuilder(peerId1, peerMap(leaderId.toString(), peerId2.toString()), PEER_MEMBER_1_NAME)),
-                    peerId1.toString());
-        peer1.underlyingActor().startDroppingMessagesOfType(ElectionTimeout.class);
-
-        TestActorRef<TestEntityOwnershipShard> peer2 = actorFactory.createTestActor(TestEntityOwnershipShard.props(
-                newShardBuilder(peerId2, peerMap(leaderId.toString(), peerId1.toString()), PEER_MEMBER_2_NAME)),
-                    peerId2.toString());
-        peer2.underlyingActor().startDroppingMessagesOfType(ElectionTimeout.class);
-
-        TestActorRef<EntityOwnershipShard> leader = actorFactory.createTestActor(
-                newShardProps(leaderId, peerMap(peerId1.toString(), peerId2.toString()), LOCAL_MEMBER_NAME),
-                    leaderId.toString());
-
-        ShardTestKit.waitUntilLeader(leader);
-
-        DOMEntity entity = new DOMEntity(ENTITY_TYPE, ENTITY_ID1);
-
-        // Add a remote candidate
-
-        peer1.tell(new RegisterCandidateLocal(entity), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        verifyCommittedEntityCandidate(leader, entity.getType(), entity.getIdentifier(), PEER_MEMBER_1_NAME);
-
-        // Register local
-
-        leader.tell(new RegisterCandidateLocal(entity), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        // Verify the remote candidate becomes owner
-
-        verifyCommittedEntityCandidate(leader, entity.getType(), entity.getIdentifier(), LOCAL_MEMBER_NAME);
-        verifyOwner(leader, entity.getType(), entity.getIdentifier(), PEER_MEMBER_1_NAME);
-
-        // Add another remote candidate and verify ownership doesn't change
-
-        peer2.tell(new RegisterCandidateLocal(entity), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        verifyCommittedEntityCandidate(leader, entity.getType(), entity.getIdentifier(), PEER_MEMBER_2_NAME);
-        Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS);
-        verifyOwner(leader, entity.getType(), entity.getIdentifier(), PEER_MEMBER_1_NAME);
-
-        // Remove the second remote candidate and verify ownership doesn't change
-
-        peer2.tell(new UnregisterCandidateLocal(entity), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        verifyEntityCandidateRemoved(leader, entity.getType(), entity.getIdentifier(), PEER_MEMBER_2_NAME);
-        Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS);
-        verifyOwner(leader, entity.getType(), entity.getIdentifier(), PEER_MEMBER_1_NAME);
-
-        // Remove the first remote candidate and verify the local candidate becomes owner
-
-        peer1.tell(new UnregisterCandidateLocal(entity), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        verifyEntityCandidateRemoved(leader, entity.getType(), entity.getIdentifier(), PEER_MEMBER_1_NAME);
-        verifyOwner(leader, entity.getType(), entity.getIdentifier(), LOCAL_MEMBER_NAME);
-
-        // Add the second remote candidate back and verify ownership doesn't change
-
-        peer2.tell(new RegisterCandidateLocal(entity), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        verifyCommittedEntityCandidate(leader, entity.getType(), entity.getIdentifier(), PEER_MEMBER_2_NAME);
-        Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS);
-        verifyOwner(leader, entity.getType(), entity.getIdentifier(), LOCAL_MEMBER_NAME);
-
-        // Unregister the local candidate and verify the second remote candidate becomes owner
-
-        leader.tell(new UnregisterCandidateLocal(entity), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        verifyEntityCandidateRemoved(leader, entity.getType(), entity.getIdentifier(), LOCAL_MEMBER_NAME);
-        verifyOwner(leader, entity.getType(), entity.getIdentifier(), PEER_MEMBER_2_NAME);
-
-        testLog.info("testOwnershipChanges ending");
-    }
-
-    @Test
-    public void testOwnerChangesOnPeerAvailabilityChanges() throws Exception {
-        testLog.info("testOwnerChangesOnPeerAvailabilityChanges starting");
-
-        final ShardTestKit kit = new ShardTestKit(getSystem());
-
-        dataStoreContextBuilder.shardHeartbeatIntervalInMillis(100).shardElectionTimeoutFactor(4)
-                .shardIsolatedLeaderCheckIntervalInMillis(100000);
-
-        ShardIdentifier leaderId = newShardId(LOCAL_MEMBER_NAME);
-        ShardIdentifier peerId1 = newShardId(PEER_MEMBER_1_NAME);
-        ShardIdentifier peerId2 = newShardId(PEER_MEMBER_2_NAME);
-
-        TestActorRef<TestEntityOwnershipShard> peer1 = actorFactory.createTestActor(TestEntityOwnershipShard.props(
-                newShardBuilder(peerId1, peerMap(leaderId.toString(), peerId2.toString()), PEER_MEMBER_1_NAME)),
-                    peerId1.toString());
-        peer1.underlyingActor().startDroppingMessagesOfType(ElectionTimeout.class);
-
-        TestActorRef<TestEntityOwnershipShard> peer2 = actorFactory.createTestActor(TestEntityOwnershipShard.props(
-                newShardBuilder(peerId2, peerMap(leaderId.toString(), peerId1.toString()), PEER_MEMBER_2_NAME)),
-                    peerId2.toString());
-        peer2.underlyingActor().startDroppingMessagesOfType(ElectionTimeout.class);
-
-        TestActorRef<EntityOwnershipShard> leader = actorFactory.createTestActor(
-                newShardProps(leaderId, peerMap(peerId1.toString(), peerId2.toString()), LOCAL_MEMBER_NAME),
-                    leaderId.toString());
-
-        verifyRaftState(leader, state ->
-                assertEquals("getRaftState", RaftState.Leader.toString(), state.getRaftState()));
-
-        // Send PeerDown and PeerUp with no entities
-
-        leader.tell(new PeerDown(peerId2.getMemberName(), peerId2.toString()), ActorRef.noSender());
-        leader.tell(new PeerUp(peerId2.getMemberName(), peerId2.toString()), ActorRef.noSender());
-
-        // Add candidates for entity1 with the local leader as the owner
-
-        leader.tell(new RegisterCandidateLocal(new DOMEntity(ENTITY_TYPE, ENTITY_ID1)), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-        verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
-
-        peer2.tell(new RegisterCandidateLocal(new DOMEntity(ENTITY_TYPE, ENTITY_ID1)), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-        verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID1, PEER_MEMBER_2_NAME);
-
-        peer1.tell(new RegisterCandidateLocal(new DOMEntity(ENTITY_TYPE, ENTITY_ID1)), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-        verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID1, PEER_MEMBER_1_NAME);
-        verifyOwner(leader, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
-
-        // Add candidates for entity2 with peerMember2 as the owner
-
-        peer2.tell(new RegisterCandidateLocal(new DOMEntity(ENTITY_TYPE, ENTITY_ID2)), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-        verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_2_NAME);
-
-        peer1.tell(new RegisterCandidateLocal(new DOMEntity(ENTITY_TYPE, ENTITY_ID2)), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-        verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_1_NAME);
-        verifyOwner(leader, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_2_NAME);
-
-        // Add candidates for entity3 with peerMember2 as the owner.
-
-        peer2.tell(new RegisterCandidateLocal(new DOMEntity(ENTITY_TYPE, ENTITY_ID3)), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-        verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID3, PEER_MEMBER_2_NAME);
-
-        leader.tell(new RegisterCandidateLocal(new DOMEntity(ENTITY_TYPE, ENTITY_ID3)), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-        verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID3, LOCAL_MEMBER_NAME);
-
-        peer1.tell(new RegisterCandidateLocal(new DOMEntity(ENTITY_TYPE, ENTITY_ID3)), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-        verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID3, PEER_MEMBER_1_NAME);
-        verifyOwner(leader, ENTITY_TYPE, ENTITY_ID3, PEER_MEMBER_2_NAME);
-
-        // Add only candidate peerMember2 for entity4.
-
-        peer2.tell(new RegisterCandidateLocal(new DOMEntity(ENTITY_TYPE, ENTITY_ID4)), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-        verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID4, PEER_MEMBER_2_NAME);
-        verifyOwner(leader, ENTITY_TYPE, ENTITY_ID4, PEER_MEMBER_2_NAME);
-
-        // Add only candidate peerMember1 for entity5.
-
-        peer1.tell(new RegisterCandidateLocal(new DOMEntity(ENTITY_TYPE, ENTITY_ID5)), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-        verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID5, PEER_MEMBER_1_NAME);
-        verifyOwner(leader, ENTITY_TYPE, ENTITY_ID5, PEER_MEMBER_1_NAME);
-
-        // Kill peerMember2 and send PeerDown - the entities (2, 3, 4) owned by peerMember2 should get a new
-        // owner selected
-
-        kit.watch(peer2);
-        peer2.tell(PoisonPill.getInstance(), ActorRef.noSender());
-        kit.expectMsgClass(Duration.ofSeconds(5), Terminated.class);
-        kit.unwatch(peer2);
-
-        leader.tell(new PeerDown(peerId2.getMemberName(), peerId2.toString()), ActorRef.noSender());
-        // Send PeerDown again - should be noop
-        leader.tell(new PeerDown(peerId2.getMemberName(), peerId2.toString()), ActorRef.noSender());
-        peer1.tell(new PeerDown(peerId2.getMemberName(), peerId2.toString()), ActorRef.noSender());
-
-        verifyOwner(leader, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
-        verifyOwner(leader, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_1_NAME);
-        verifyOwner(leader, ENTITY_TYPE, ENTITY_ID3, LOCAL_MEMBER_NAME);
-        // no other candidates for entity4 so peerMember2 should remain owner.
-        verifyOwner(leader, ENTITY_TYPE, ENTITY_ID4, PEER_MEMBER_2_NAME);
-
-        verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID1, PEER_MEMBER_2_NAME);
-        verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_2_NAME);
-        verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID3, PEER_MEMBER_2_NAME);
-        verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID4, PEER_MEMBER_2_NAME);
-
-        // Reinstate peerMember2
-
-        peer2 = actorFactory.createTestActor(TestEntityOwnershipShard.props(
-                newShardBuilder(peerId2, peerMap(leaderId.toString(), peerId1.toString()), PEER_MEMBER_2_NAME)),
-                    peerId2.toString());
-        peer2.underlyingActor().startDroppingMessagesOfType(ElectionTimeout.class);
-        leader.tell(new PeerUp(peerId2.getMemberName(), peerId2.toString()), ActorRef.noSender());
-        // Send PeerUp again - should be noop
-        leader.tell(new PeerUp(peerId2.getMemberName(), peerId2.toString()), ActorRef.noSender());
-        peer1.tell(new PeerUp(peerId2.getMemberName(), peerId2.toString()), ActorRef.noSender());
-
-        // peerMember2's candidates should be removed on startup.
-        verifyNoEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID1, PEER_MEMBER_2_NAME);
-        verifyNoEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_2_NAME);
-        verifyNoEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID3, PEER_MEMBER_2_NAME);
-        verifyNoEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID4, PEER_MEMBER_2_NAME);
-
-        verifyOwner(leader, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
-        verifyOwner(leader, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_1_NAME);
-        verifyOwner(leader, ENTITY_TYPE, ENTITY_ID3, LOCAL_MEMBER_NAME);
-        verifyOwner(leader, ENTITY_TYPE, ENTITY_ID4, "");
-
-        // Add back candidate peerMember2 for entities 1, 2, & 3.
-
-        peer2.tell(new RegisterCandidateLocal(new DOMEntity(ENTITY_TYPE, ENTITY_ID1)), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-        peer2.tell(new RegisterCandidateLocal(new DOMEntity(ENTITY_TYPE, ENTITY_ID2)), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-        peer2.tell(new RegisterCandidateLocal(new DOMEntity(ENTITY_TYPE, ENTITY_ID3)), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-        verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID1, PEER_MEMBER_2_NAME);
-        verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_2_NAME);
-        verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID3, PEER_MEMBER_2_NAME);
-        verifyCommittedEntityCandidate(peer2, ENTITY_TYPE, ENTITY_ID1, PEER_MEMBER_2_NAME);
-        verifyCommittedEntityCandidate(peer2, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_2_NAME);
-        verifyCommittedEntityCandidate(peer2, ENTITY_TYPE, ENTITY_ID3, PEER_MEMBER_2_NAME);
-        verifyOwner(leader, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
-        verifyOwner(leader, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_1_NAME);
-        verifyOwner(leader, ENTITY_TYPE, ENTITY_ID3, LOCAL_MEMBER_NAME);
-        verifyOwner(peer2, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
-        verifyOwner(peer2, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_1_NAME);
-        verifyOwner(peer2, ENTITY_TYPE, ENTITY_ID3, LOCAL_MEMBER_NAME);
-        verifyOwner(peer2, ENTITY_TYPE, ENTITY_ID4, "");
-
-        // Kill peerMember1 and send PeerDown - entity 2 should get a new owner selected
-
-        kit.watch(peer1);
-        peer1.tell(PoisonPill.getInstance(), ActorRef.noSender());
-        kit.expectMsgClass(Duration.ofSeconds(5), Terminated.class);
-        kit.unwatch(peer1);
-        leader.tell(new PeerDown(peerId1.getMemberName(), peerId1.toString()), ActorRef.noSender());
-
-        verifyOwner(leader, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_2_NAME);
-
-        // Verify the reinstated peerMember2 is fully synced.
-
-        verifyOwner(peer2, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
-        verifyOwner(peer2, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_2_NAME);
-        verifyOwner(peer2, ENTITY_TYPE, ENTITY_ID3, LOCAL_MEMBER_NAME);
-        verifyOwner(peer2, ENTITY_TYPE, ENTITY_ID4, "");
-
-        // Reinstate peerMember1 and verify no owner changes
-
-        peer1 = actorFactory.createTestActor(TestEntityOwnershipShard.props(newShardBuilder(
-                peerId1, peerMap(leaderId.toString(), peerId2.toString()), PEER_MEMBER_1_NAME)), peerId1.toString());
-        peer1.underlyingActor().startDroppingMessagesOfType(ElectionTimeout.class);
-        leader.tell(new PeerUp(peerId1.getMemberName(), peerId1.toString()), ActorRef.noSender());
-
-        verifyOwner(leader, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
-        verifyOwner(leader, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_2_NAME);
-        verifyOwner(leader, ENTITY_TYPE, ENTITY_ID3, LOCAL_MEMBER_NAME);
-        verifyOwner(leader, ENTITY_TYPE, ENTITY_ID4, "");
-
-        verifyNoEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID1, PEER_MEMBER_1_NAME);
-        verifyNoEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_1_NAME);
-        verifyNoEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID3, PEER_MEMBER_1_NAME);
-
-        verifyNoEntityCandidate(peer2, ENTITY_TYPE, ENTITY_ID1, PEER_MEMBER_1_NAME);
-        verifyNoEntityCandidate(peer2, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_1_NAME);
-        verifyNoEntityCandidate(peer2, ENTITY_TYPE, ENTITY_ID3, PEER_MEMBER_1_NAME);
-
-        // Verify the reinstated peerMember1 is fully synced.
-
-        verifyOwner(peer1, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
-        verifyOwner(peer1, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_2_NAME);
-        verifyOwner(peer1, ENTITY_TYPE, ENTITY_ID3, LOCAL_MEMBER_NAME);
-        verifyOwner(peer1, ENTITY_TYPE, ENTITY_ID4, "");
-
-        AtomicLong leaderLastApplied = new AtomicLong();
-        verifyRaftState(leader, rs -> {
-            assertEquals("LastApplied up-to-date", rs.getLastApplied(), rs.getLastIndex());
-            leaderLastApplied.set(rs.getLastApplied());
-        });
-
-        verifyRaftState(peer2, rs -> assertEquals("LastApplied", leaderLastApplied.get(), rs.getLastIndex()));
-
-        // Kill the local leader and elect peer2 the leader. This should cause a new owner to be selected for
-        // the entities (1 and 3) previously owned by the local leader member.
-
-        peer2.tell(new PeerAddressResolved(peerId1.toString(), peer1.path().toString()), ActorRef.noSender());
-        peer2.tell(new PeerUp(leaderId.getMemberName(), leaderId.toString()), ActorRef.noSender());
-        peer2.tell(new PeerUp(peerId1.getMemberName(), peerId1.toString()), ActorRef.noSender());
-
-        kit.watch(leader);
-        leader.tell(PoisonPill.getInstance(), ActorRef.noSender());
-        kit.expectMsgClass(Duration.ofSeconds(5), Terminated.class);
-        kit.unwatch(leader);
-        peer2.tell(new PeerDown(leaderId.getMemberName(), leaderId.toString()), ActorRef.noSender());
-        peer2.tell(TimeoutNow.INSTANCE, peer2);
-
-        verifyRaftState(peer2, state ->
-                assertEquals("getRaftState", RaftState.Leader.toString(), state.getRaftState()));
-
-        verifyOwner(peer2, ENTITY_TYPE, ENTITY_ID1, PEER_MEMBER_2_NAME);
-        verifyOwner(peer2, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_2_NAME);
-        verifyOwner(peer2, ENTITY_TYPE, ENTITY_ID3, PEER_MEMBER_2_NAME);
-        verifyOwner(peer2, ENTITY_TYPE, ENTITY_ID4, "");
-
-        testLog.info("testOwnerChangesOnPeerAvailabilityChanges ending");
-    }
-
-    @Test
-    public void testLeaderIsolation() throws Exception {
-        testLog.info("testLeaderIsolation starting");
-
-        final ShardTestKit kit = new ShardTestKit(getSystem());
-
-        ShardIdentifier leaderId = newShardId(LOCAL_MEMBER_NAME);
-        ShardIdentifier peerId1 = newShardId(PEER_MEMBER_1_NAME);
-        ShardIdentifier peerId2 = newShardId(PEER_MEMBER_2_NAME);
-
-        dataStoreContextBuilder.shardHeartbeatIntervalInMillis(100).shardElectionTimeoutFactor(4)
-                .shardIsolatedLeaderCheckIntervalInMillis(100000);
-
-        TestActorRef<TestEntityOwnershipShard> peer1 = actorFactory.createTestActor(TestEntityOwnershipShard.props(
-                newShardBuilder(peerId1, peerMap(leaderId.toString(), peerId2.toString()), PEER_MEMBER_1_NAME)),
-                    peerId1.toString());
-        peer1.underlyingActor().startDroppingMessagesOfType(ElectionTimeout.class);
-
-        TestActorRef<TestEntityOwnershipShard> peer2 = actorFactory.createTestActor(TestEntityOwnershipShard.props(
-                newShardBuilder(peerId2, peerMap(leaderId.toString(), peerId1.toString()), PEER_MEMBER_2_NAME)),
-                    peerId2.toString());
-        peer2.underlyingActor().startDroppingMessagesOfType(ElectionTimeout.class);
-
-        dataStoreContextBuilder = DatastoreContext.newBuilderFrom(dataStoreContextBuilder.build())
-                .shardIsolatedLeaderCheckIntervalInMillis(500);
-
-        TestActorRef<TestEntityOwnershipShard> leader = actorFactory.createTestActor(TestEntityOwnershipShard.props(
-                newShardBuilder(leaderId, peerMap(peerId1.toString(), peerId2.toString()), LOCAL_MEMBER_NAME)),
-                    leaderId.toString());
-
-        ShardTestKit.waitUntilLeader(leader);
-
-        // Add entity1 candidates for all members with the leader as the owner
-
-        DOMEntity entity1 = new DOMEntity(ENTITY_TYPE, ENTITY_ID1);
-        leader.tell(new RegisterCandidateLocal(entity1), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-        verifyCommittedEntityCandidate(leader, entity1.getType(), entity1.getIdentifier(), LOCAL_MEMBER_NAME);
-
-        peer1.tell(new RegisterCandidateLocal(entity1), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-        verifyCommittedEntityCandidate(leader, entity1.getType(), entity1.getIdentifier(), PEER_MEMBER_1_NAME);
-
-        peer2.tell(new RegisterCandidateLocal(entity1), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-        verifyCommittedEntityCandidate(leader, entity1.getType(), entity1.getIdentifier(), PEER_MEMBER_2_NAME);
-
-        verifyOwner(leader, entity1.getType(), entity1.getIdentifier(), LOCAL_MEMBER_NAME);
-        verifyOwner(peer1, entity1.getType(), entity1.getIdentifier(), LOCAL_MEMBER_NAME);
-        verifyOwner(peer2, entity1.getType(), entity1.getIdentifier(), LOCAL_MEMBER_NAME);
-
-        // Add entity2 candidates for all members with peer1 as the owner
-
-        DOMEntity entity2 = new DOMEntity(ENTITY_TYPE, ENTITY_ID2);
-        peer1.tell(new RegisterCandidateLocal(entity2), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-        verifyCommittedEntityCandidate(leader, entity2.getType(), entity2.getIdentifier(), PEER_MEMBER_1_NAME);
-
-        peer2.tell(new RegisterCandidateLocal(entity2), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-        verifyCommittedEntityCandidate(leader, entity2.getType(), entity2.getIdentifier(), PEER_MEMBER_2_NAME);
-
-        leader.tell(new RegisterCandidateLocal(entity2), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-        verifyCommittedEntityCandidate(leader, entity2.getType(), entity2.getIdentifier(), LOCAL_MEMBER_NAME);
-
-        verifyOwner(leader, entity2.getType(), entity2.getIdentifier(), PEER_MEMBER_1_NAME);
-        verifyOwner(peer1, entity2.getType(), entity2.getIdentifier(), PEER_MEMBER_1_NAME);
-        verifyOwner(peer2, entity2.getType(), entity2.getIdentifier(), PEER_MEMBER_1_NAME);
-
-        // Add entity3 candidates for all members with peer2 as the owner
-
-        DOMEntity entity3 = new DOMEntity(ENTITY_TYPE, ENTITY_ID3);
-        peer2.tell(new RegisterCandidateLocal(entity3), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-        verifyCommittedEntityCandidate(leader, entity3.getType(), entity3.getIdentifier(), PEER_MEMBER_2_NAME);
-
-        leader.tell(new RegisterCandidateLocal(entity3), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-        verifyCommittedEntityCandidate(leader, entity3.getType(), entity3.getIdentifier(), LOCAL_MEMBER_NAME);
-
-        peer1.tell(new RegisterCandidateLocal(entity3), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-        verifyCommittedEntityCandidate(leader, entity3.getType(), entity3.getIdentifier(), PEER_MEMBER_1_NAME);
-
-        verifyOwner(leader, entity3.getType(), entity3.getIdentifier(), PEER_MEMBER_2_NAME);
-        verifyOwner(peer1, entity3.getType(), entity3.getIdentifier(), PEER_MEMBER_2_NAME);
-        verifyOwner(peer2, entity3.getType(), entity3.getIdentifier(), PEER_MEMBER_2_NAME);
-
-        // Add listeners on all members
-
-        DOMEntityOwnershipListener leaderListener = mock(DOMEntityOwnershipListener.class);
-        leader.tell(new RegisterListenerLocal(leaderListener, ENTITY_TYPE), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-        verify(leaderListener, timeout(5000).times(3)).ownershipChanged(or(or(
-                ownershipChange(entity1, false, true, true), ownershipChange(entity2, false, false, true)),
-                ownershipChange(entity3, false, false, true)));
-        reset(leaderListener);
-
-        DOMEntityOwnershipListener peer1Listener = mock(DOMEntityOwnershipListener.class);
-        peer1.tell(new RegisterListenerLocal(peer1Listener, ENTITY_TYPE), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-        verify(peer1Listener, timeout(5000).times(3)).ownershipChanged(or(or(
-                ownershipChange(entity1, false, false, true), ownershipChange(entity2, false, true, true)),
-                ownershipChange(entity3, false, false, true)));
-        reset(peer1Listener);
-
-        DOMEntityOwnershipListener peer2Listener = mock(DOMEntityOwnershipListener.class);
-        peer2.tell(new RegisterListenerLocal(peer2Listener, ENTITY_TYPE), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-        verify(peer2Listener, timeout(5000).times(3)).ownershipChanged(or(or(
-                ownershipChange(entity1, false, false, true), ownershipChange(entity2, false, false, true)),
-                ownershipChange(entity3, false, true, true)));
-        reset(peer2Listener);
-
-        // Isolate the leader by dropping AppendEntries to the followers and incoming messages from the followers.
-
-        leader.underlyingActor().startDroppingMessagesOfType(RequestVote.class);
-        leader.underlyingActor().startDroppingMessagesOfType(AppendEntries.class);
-
-        peer2.underlyingActor().startDroppingMessagesOfType(AppendEntries.class,
-            ae -> ae.getLeaderId().equals(leaderId.toString()));
-        peer1.underlyingActor().startDroppingMessagesOfType(AppendEntries.class);
-
-        // Make peer1 start an election and become leader by enabling the ElectionTimeout message.
-
-        peer1.underlyingActor().stopDroppingMessagesOfType(ElectionTimeout.class);
-
-        // Send PeerDown to the isolated leader so it tries to re-assign ownership for the entities owned by the
-        // isolated peers.
-
-        leader.tell(new PeerDown(peerId1.getMemberName(), peerId1.toString()), ActorRef.noSender());
-        leader.tell(new PeerDown(peerId2.getMemberName(), peerId2.toString()), ActorRef.noSender());
-
-        verifyRaftState(leader, state ->
-                assertEquals("getRaftState", RaftState.IsolatedLeader.toString(), state.getRaftState()));
-
-        // Expect inJeopardy notification on the isolated leader.
-
-        verify(leaderListener, timeout(5000).times(3)).ownershipChanged(or(or(
-                ownershipChange(entity1, true, true, true, true), ownershipChange(entity2, false, false, true, true)),
-                ownershipChange(entity3, false, false, true, true)));
-        reset(leaderListener);
-
-        verifyRaftState(peer1, state ->
-                assertEquals("getRaftState", RaftState.Leader.toString(), state.getRaftState()));
-
-        // Send PeerDown to the new leader peer1 so it re-assigns ownership for the entities owned by the
-        // isolated leader.
-
-        peer1.tell(new PeerDown(leaderId.getMemberName(), leaderId.toString()), ActorRef.noSender());
-
-        verifyOwner(peer1, entity1.getType(), entity1.getIdentifier(), PEER_MEMBER_1_NAME);
-
-        verify(peer1Listener, timeout(5000)).ownershipChanged(ownershipChange(entity1, false, true, true));
-        reset(peer1Listener);
-
-        verify(peer2Listener, timeout(5000)).ownershipChanged(ownershipChange(entity1, false, false, true));
-        reset(peer2Listener);
-
-        // Remove the isolation.
-
-        leader.underlyingActor().stopDroppingMessagesOfType(RequestVote.class);
-        leader.underlyingActor().stopDroppingMessagesOfType(AppendEntries.class);
-        peer2.underlyingActor().stopDroppingMessagesOfType(AppendEntries.class);
-        peer1.underlyingActor().stopDroppingMessagesOfType(AppendEntries.class);
-
-        // Previous leader should switch to Follower and send inJeopardy cleared notifications for all entities.
-
-        verifyRaftState(leader, state ->
-                assertEquals("getRaftState", RaftState.Follower.toString(), state.getRaftState()));
-
-        verify(leaderListener, timeout(5000).times(3)).ownershipChanged(or(or(
-                ownershipChange(entity1, true, true, true), ownershipChange(entity2, false, false, true)),
-                ownershipChange(entity3, false, false, true)));
-
-        verifyOwner(leader, entity1.getType(), entity1.getIdentifier(), PEER_MEMBER_1_NAME);
-        verify(leaderListener, timeout(5000)).ownershipChanged(ownershipChange(entity1, true, false, true));
-
-        Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS);
-        verifyOwner(leader, entity2.getType(), entity2.getIdentifier(), PEER_MEMBER_1_NAME);
-        verifyOwner(leader, entity3.getType(), entity3.getIdentifier(), PEER_MEMBER_2_NAME);
-
-        verifyNoMoreInteractions(leaderListener);
-        verifyNoMoreInteractions(peer1Listener);
-        verifyNoMoreInteractions(peer2Listener);
-
-        testLog.info("testLeaderIsolation ending");
-    }
-
-    @Test
-    public void testLeaderIsolationWithPendingCandidateAdded() throws Exception {
-        testLog.info("testLeaderIsolationWithPendingCandidateAdded starting");
-
-        final ShardTestKit kit = new ShardTestKit(getSystem());
-
-        ShardIdentifier leaderId = newShardId(LOCAL_MEMBER_NAME);
-        ShardIdentifier peerId1 = newShardId(PEER_MEMBER_1_NAME);
-        ShardIdentifier peerId2 = newShardId(PEER_MEMBER_2_NAME);
-
-        dataStoreContextBuilder.shardHeartbeatIntervalInMillis(100).shardElectionTimeoutFactor(4)
-                .shardIsolatedLeaderCheckIntervalInMillis(100000);
-
-        TestActorRef<TestEntityOwnershipShard> peer1 = actorFactory.createTestActor(TestEntityOwnershipShard.props(
-                newShardBuilder(peerId1, peerMap(leaderId.toString(), peerId2.toString()), PEER_MEMBER_1_NAME),
-                actorFactory.createActor(MessageCollectorActor.props())), peerId1.toString());
-        peer1.underlyingActor().startDroppingMessagesOfType(ElectionTimeout.class);
-
-        TestActorRef<TestEntityOwnershipShard> peer2 = actorFactory.createTestActor(TestEntityOwnershipShard.props(
-                newShardBuilder(peerId2, peerMap(leaderId.toString(), peerId1.toString()), PEER_MEMBER_2_NAME),
-                actorFactory.createTestActor(MessageCollectorActor.props())), peerId2.toString());
-        peer2.underlyingActor().startDroppingMessagesOfType(ElectionTimeout.class);
-
-        dataStoreContextBuilder = DatastoreContext.newBuilderFrom(dataStoreContextBuilder.build())
-                .shardIsolatedLeaderCheckIntervalInMillis(500);
-
-        TestActorRef<TestEntityOwnershipShard> leader = actorFactory.createTestActor(TestEntityOwnershipShard.props(
-                newShardBuilder(leaderId, peerMap(peerId1.toString(), peerId2.toString()), LOCAL_MEMBER_NAME),
-                actorFactory.createTestActor(MessageCollectorActor.props())), leaderId.toString());
-
-        ShardTestKit.waitUntilLeader(leader);
-
-        // Add listeners on all members
-
-        DOMEntityOwnershipListener leaderListener = mock(DOMEntityOwnershipListener.class,
-                "DOMEntityOwnershipListener-" + LOCAL_MEMBER_NAME);
-        leader.tell(new RegisterListenerLocal(leaderListener, ENTITY_TYPE), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        DOMEntityOwnershipListener peer1Listener = mock(DOMEntityOwnershipListener.class,
-                "DOMEntityOwnershipListener-" + PEER_MEMBER_1_NAME);
-        peer1.tell(new RegisterListenerLocal(peer1Listener, ENTITY_TYPE), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        DOMEntityOwnershipListener peer2Listener = mock(DOMEntityOwnershipListener.class,
-                "DOMEntityOwnershipListener-" + PEER_MEMBER_2_NAME);
-        peer2.tell(new RegisterListenerLocal(peer2Listener, ENTITY_TYPE), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        // Drop the CandidateAdded message to the leader for now.
-
-        leader.underlyingActor().startDroppingMessagesOfType(CandidateAdded.class);
-
-        // Add an entity candidates for the leader. Since we've blocked the CandidateAdded message, it won't be
-        // assigned the owner.
-
-        DOMEntity entity1 = new DOMEntity(ENTITY_TYPE, ENTITY_ID1);
-        leader.tell(new RegisterCandidateLocal(entity1), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-        verifyCommittedEntityCandidate(leader, entity1.getType(), entity1.getIdentifier(), LOCAL_MEMBER_NAME);
-        verifyCommittedEntityCandidate(peer1, entity1.getType(), entity1.getIdentifier(), LOCAL_MEMBER_NAME);
-        verifyCommittedEntityCandidate(peer2, entity1.getType(), entity1.getIdentifier(), LOCAL_MEMBER_NAME);
-
-        DOMEntity entity2 = new DOMEntity(ENTITY_TYPE, ENTITY_ID2);
-        leader.tell(new RegisterCandidateLocal(entity2), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-        verifyCommittedEntityCandidate(leader, entity2.getType(), entity2.getIdentifier(), LOCAL_MEMBER_NAME);
-        verifyCommittedEntityCandidate(peer1, entity2.getType(), entity2.getIdentifier(), LOCAL_MEMBER_NAME);
-        verifyCommittedEntityCandidate(peer2, entity2.getType(), entity2.getIdentifier(), LOCAL_MEMBER_NAME);
-
-        // Capture the CandidateAdded messages.
-
-        final List<CandidateAdded> candidateAdded = expectMatching(leader.underlyingActor().collectorActor(),
-                CandidateAdded.class, 2);
-
-        // Drop AppendEntries to the followers containing a log entry, which will be for the owner writes after we
-        // forward the CandidateAdded messages to the leader. This will leave the pending owner write tx's uncommitted.
-
-        peer1.underlyingActor().startDroppingMessagesOfType(AppendEntries.class, ae -> ae.getEntries().size() > 0);
-        peer2.underlyingActor().startDroppingMessagesOfType(AppendEntries.class, ae -> ae.getEntries().size() > 0);
-
-        // Now forward the CandidateAdded messages to the leader and wait for it to send out the AppendEntries.
-
-        leader.underlyingActor().stopDroppingMessagesOfType(CandidateAdded.class);
-        leader.tell(candidateAdded.get(0), leader);
-        leader.tell(candidateAdded.get(1), leader);
-
-        expectMatching(peer1.underlyingActor().collectorActor(), AppendEntries.class, 2,
-            ae -> ae.getEntries().size() > 0);
-
-        // Verify no owner assigned.
-
-        verifyNoOwnerSet(leader, entity1.getType(), entity1.getIdentifier());
-        verifyNoOwnerSet(leader, entity2.getType(), entity2.getIdentifier());
-
-        // Isolate the leader by dropping AppendEntries to the followers and incoming messages from the followers.
-
-        leader.underlyingActor().startDroppingMessagesOfType(RequestVote.class);
-        leader.underlyingActor().startDroppingMessagesOfType(AppendEntries.class);
-
-        peer2.underlyingActor().startDroppingMessagesOfType(AppendEntries.class,
-            ae -> ae.getLeaderId().equals(leaderId.toString()));
-        peer1.underlyingActor().startDroppingMessagesOfType(AppendEntries.class);
-
-        // Send PeerDown to the isolated leader - should be no-op since there's no owned entities.
-
-        leader.tell(new PeerDown(peerId1.getMemberName(), peerId1.toString()), ActorRef.noSender());
-        leader.tell(new PeerDown(peerId2.getMemberName(), peerId2.toString()), ActorRef.noSender());
-
-        // Verify the leader transitions to IsolatedLeader.
-
-        verifyRaftState(leader, state -> assertEquals("getRaftState", RaftState.IsolatedLeader.toString(),
-                state.getRaftState()));
-
-        // Send PeerDown to the new leader peer1.
-
-        peer1.tell(new PeerDown(leaderId.getMemberName(), leaderId.toString()), ActorRef.noSender());
-
-        // Make peer1 start an election and become leader by sending the TimeoutNow message.
-
-        peer1.tell(TimeoutNow.INSTANCE, ActorRef.noSender());
-
-        // Verify the peer1 transitions to Leader.
-
-        verifyRaftState(peer1, state -> assertEquals("getRaftState", RaftState.Leader.toString(),
-                state.getRaftState()));
-
-        verifyNoOwnerSet(peer1, entity1.getType(), entity1.getIdentifier());
-        verifyNoOwnerSet(peer2, entity1.getType(), entity2.getIdentifier());
-
-        verifyNoMoreInteractions(peer1Listener);
-        verifyNoMoreInteractions(peer2Listener);
-
-        // Add candidate peer1 candidate for entity2.
-
-        peer1.tell(new RegisterCandidateLocal(entity2), kit.getRef());
-
-        verifyOwner(peer1, entity2.getType(), entity2.getIdentifier(), PEER_MEMBER_1_NAME);
-        verify(peer1Listener, timeout(5000)).ownershipChanged(ownershipChange(entity2, false, true, true));
-        verify(peer2Listener, timeout(5000)).ownershipChanged(ownershipChange(entity2, false, false, true));
-
-        reset(leaderListener, peer1Listener, peer2Listener);
-
-        // Remove the isolation.
-
-        leader.underlyingActor().stopDroppingMessagesOfType(RequestVote.class);
-        leader.underlyingActor().stopDroppingMessagesOfType(AppendEntries.class);
-        peer2.underlyingActor().stopDroppingMessagesOfType(AppendEntries.class);
-        peer1.underlyingActor().stopDroppingMessagesOfType(AppendEntries.class);
-
-        // Previous leader should switch to Follower.
-
-        verifyRaftState(leader, state -> assertEquals("getRaftState", RaftState.Follower.toString(),
-                state.getRaftState()));
-
-        // Send PeerUp to peer1 and peer2.
-
-        peer1.tell(new PeerUp(leaderId.getMemberName(), leaderId.toString()), ActorRef.noSender());
-        peer2.tell(new PeerUp(leaderId.getMemberName(), leaderId.toString()), ActorRef.noSender());
-
-        // The previous leader should become the owner of entity1.
-
-        verifyOwner(leader, entity1.getType(), entity1.getIdentifier(), LOCAL_MEMBER_NAME);
-
-        // The previous leader's DOMEntityOwnershipListener should get 4 total notifications:
-        //     - inJeopardy cleared for entity1 (wasOwner=false, isOwner=false, hasOwner=false, inJeopardy=false)
-        //     - inJeopardy cleared for entity2 (wasOwner=false, isOwner=false, hasOwner=false, inJeopardy=false)
-        //     - local owner granted for entity1 (wasOwner=false, isOwner=true, hasOwner=true, inJeopardy=false)
-        //     - remote owner for entity2 (wasOwner=false, isOwner=false, hasOwner=true, inJeopardy=false)
-        verify(leaderListener, timeout(5000).times(4)).ownershipChanged(or(
-                or(ownershipChange(entity1, false, false, false), ownershipChange(entity2, false, false, false)),
-                or(ownershipChange(entity1, false, true, true), ownershipChange(entity2, false, false, true))));
-
-        verify(peer1Listener, timeout(5000)).ownershipChanged(ownershipChange(entity1, false, false, true));
-        verify(peer2Listener, timeout(5000)).ownershipChanged(ownershipChange(entity1, false, false, true));
-
-        // Verify entity2's owner doesn't change.
-
-        Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS);
-        verifyOwner(peer1, entity2.getType(), entity2.getIdentifier(), PEER_MEMBER_1_NAME);
-
-        verifyNoMoreInteractions(leaderListener);
-        verifyNoMoreInteractions(peer1Listener);
-        verifyNoMoreInteractions(peer2Listener);
-
-        testLog.info("testLeaderIsolationWithPendingCandidateAdded ending");
-    }
-
-    @Test
-    public void testListenerRegistration() {
-        testLog.info("testListenerRegistration starting");
-
-        ShardTestKit kit = new ShardTestKit(getSystem());
-
-        ShardIdentifier leaderId = newShardId(LOCAL_MEMBER_NAME);
-        ShardIdentifier peerId = newShardId(PEER_MEMBER_1_NAME);
-
-        TestActorRef<TestEntityOwnershipShard> peer = actorFactory.createTestActor(TestEntityOwnershipShard.props(
-                newShardBuilder(peerId, peerMap(leaderId.toString()), PEER_MEMBER_1_NAME)), peerId.toString());
-        peer.underlyingActor().startDroppingMessagesOfType(ElectionTimeout.class);
-
-        TestActorRef<EntityOwnershipShard> leader = actorFactory.createTestActor(
-                newShardProps(leaderId, peerMap(peerId.toString()), LOCAL_MEMBER_NAME), leaderId.toString());
-
-        ShardTestKit.waitUntilLeader(leader);
-
-        String otherEntityType = "otherEntityType";
-        final DOMEntity entity1 = new DOMEntity(ENTITY_TYPE, ENTITY_ID1);
-        final DOMEntity entity2 = new DOMEntity(ENTITY_TYPE, ENTITY_ID2);
-        final DOMEntity entity3 = new DOMEntity(ENTITY_TYPE, ENTITY_ID3);
-        final DOMEntity entity4 = new DOMEntity(otherEntityType, ENTITY_ID3);
-        DOMEntityOwnershipListener listener = mock(DOMEntityOwnershipListener.class);
-
-        // Register listener
-
-        leader.tell(new RegisterListenerLocal(listener, ENTITY_TYPE), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        // Register a couple candidates for the desired entity type and verify listener is notified.
-
-        leader.tell(new RegisterCandidateLocal(entity1), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        verify(listener, timeout(5000)).ownershipChanged(ownershipChange(entity1, false, true, true));
-
-        leader.tell(new RegisterCandidateLocal(entity2), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        verify(listener, timeout(5000)).ownershipChanged(ownershipChange(entity2, false, true, true));
-        reset(listener);
-
-        // Register another candidate for another entity type and verify listener is not notified.
-
-        leader.tell(new RegisterCandidateLocal(entity4), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS);
-        verify(listener, never()).ownershipChanged(ownershipChange(entity4));
-
-        // Register remote candidate for entity1
-
-        peer.tell(new RegisterCandidateLocal(entity1), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-        verifyCommittedEntityCandidate(leader, ENTITY_TYPE, entity1.getIdentifier(), PEER_MEMBER_1_NAME);
-
-        // Unregister the local candidate for entity1 and verify listener is notified
-
-        leader.tell(new UnregisterCandidateLocal(entity1), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        verify(listener, timeout(5000)).ownershipChanged(ownershipChange(entity1, true, false, true));
-        reset(listener);
-
-        // Unregister the listener, add a candidate for entity3 and verify listener isn't notified
-
-        leader.tell(new UnregisterListenerLocal(listener, ENTITY_TYPE), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        leader.tell(new RegisterCandidateLocal(entity3), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        verifyOwner(leader, ENTITY_TYPE, entity3.getIdentifier(), LOCAL_MEMBER_NAME);
-        Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS);
-        verify(listener, never()).ownershipChanged(any(DOMEntityOwnershipChange.class));
-
-        // Re-register the listener and verify it gets notified of currently owned entities
-
-        reset(listener);
-
-        leader.tell(new RegisterListenerLocal(listener, ENTITY_TYPE), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        verify(listener, timeout(5000).times(2)).ownershipChanged(or(ownershipChange(entity2, false, true, true),
-                ownershipChange(entity3, false, true, true)));
-        Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
-        verify(listener, never()).ownershipChanged(ownershipChange(entity4));
-        verify(listener, times(1)).ownershipChanged(ownershipChange(entity1));
-
-        testLog.info("testListenerRegistration ending");
-    }
-
-    @Test
-    public void testDelayedEntityOwnerSelectionWhenMaxPeerRequestsReceived() {
-        testLog.info("testDelayedEntityOwnerSelectionWhenMaxPeerRequestsReceived starting");
-
-        ShardTestKit kit = new ShardTestKit(getSystem());
-        EntityOwnerSelectionStrategyConfig.Builder builder = EntityOwnerSelectionStrategyConfig.newBuilder()
-                .addStrategy(ENTITY_TYPE, LastCandidateSelectionStrategy.class, 500);
-
-        ShardIdentifier leaderId = newShardId(LOCAL_MEMBER_NAME);
-        ShardIdentifier peerId = newShardId(PEER_MEMBER_1_NAME);
-
-        TestActorRef<TestEntityOwnershipShard> peer = actorFactory.createTestActor(TestEntityOwnershipShard.props(
-                newShardBuilder(peerId, peerMap(leaderId.toString()), PEER_MEMBER_1_NAME)), peerId.toString());
-        peer.underlyingActor().startDroppingMessagesOfType(ElectionTimeout.class);
-
-        TestActorRef<EntityOwnershipShard> leader = actorFactory.createTestActor(
-                newShardProps(leaderId, peerMap(peerId.toString()), LOCAL_MEMBER_NAME, builder.build()),
-                leaderId.toString());
-
-        ShardTestKit.waitUntilLeader(leader);
-
-        DOMEntity entity = new DOMEntity(ENTITY_TYPE, ENTITY_ID1);
-
-        // Add a remote candidate
-
-        peer.tell(new RegisterCandidateLocal(entity), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        // Register local
-
-        leader.tell(new RegisterCandidateLocal(entity), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        // Verify the local candidate becomes owner
-
-        verifyCommittedEntityCandidate(leader, entity.getType(), entity.getIdentifier(), PEER_MEMBER_1_NAME);
-        verifyCommittedEntityCandidate(leader, entity.getType(), entity.getIdentifier(), LOCAL_MEMBER_NAME);
-        verifyOwner(leader, entity.getType(), entity.getIdentifier(), LOCAL_MEMBER_NAME);
-
-        testLog.info("testDelayedEntityOwnerSelectionWhenMaxPeerRequestsReceived ending");
-    }
-
-    @Test
-    public void testDelayedEntityOwnerSelection() {
-        testLog.info("testDelayedEntityOwnerSelection starting");
-
-        final ShardTestKit kit = new ShardTestKit(getSystem());
-        EntityOwnerSelectionStrategyConfig.Builder builder = EntityOwnerSelectionStrategyConfig.newBuilder()
-                .addStrategy(ENTITY_TYPE, LastCandidateSelectionStrategy.class, 500);
-
-        dataStoreContextBuilder.shardHeartbeatIntervalInMillis(100).shardElectionTimeoutFactor(2);
-
-        ShardIdentifier leaderId = newShardId(LOCAL_MEMBER_NAME);
-        ShardIdentifier peerId1 = newShardId(PEER_MEMBER_1_NAME);
-        ShardIdentifier peerId2 = newShardId(PEER_MEMBER_2_NAME);
-
-        TestActorRef<TestEntityOwnershipShard> peer1 = actorFactory.createTestActor(TestEntityOwnershipShard.props(
-                newShardBuilder(peerId1, peerMap(leaderId.toString(), peerId2.toString()), PEER_MEMBER_1_NAME)),
-                    peerId1.toString());
-        peer1.underlyingActor().startDroppingMessagesOfType(ElectionTimeout.class);
-
-        TestActorRef<TestEntityOwnershipShard> peer2 = actorFactory.createTestActor(TestEntityOwnershipShard.props(
-                newShardBuilder(peerId2, peerMap(leaderId.toString(), peerId1.toString()), PEER_MEMBER_2_NAME)),
-                    peerId2.toString());
-        peer2.underlyingActor().startDroppingMessagesOfType(ElectionTimeout.class);
-
-        TestActorRef<EntityOwnershipShard> leader = actorFactory.createTestActor(
-                newShardProps(leaderId, peerMap(peerId1.toString(), peerId2.toString()), LOCAL_MEMBER_NAME,
-                        builder.build()), leaderId.toString());
-
-        ShardTestKit.waitUntilLeader(leader);
-
-        DOMEntity entity = new DOMEntity(ENTITY_TYPE, ENTITY_ID1);
-
-        // Add a remote candidate
-
-        peer1.tell(new RegisterCandidateLocal(entity), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        // Register local
-
-        leader.tell(new RegisterCandidateLocal(entity), kit.getRef());
-        kit.expectMsgClass(SuccessReply.class);
-
-        // Verify the local candidate becomes owner
-
-        verifyCommittedEntityCandidate(leader, entity.getType(), entity.getIdentifier(), PEER_MEMBER_1_NAME);
-        verifyCommittedEntityCandidate(leader, entity.getType(), entity.getIdentifier(), LOCAL_MEMBER_NAME);
-        verifyOwner(leader, entity.getType(), entity.getIdentifier(), LOCAL_MEMBER_NAME);
-
-        testLog.info("testDelayedEntityOwnerSelection ending");
-    }
-
-    private Props newLocalShardProps() {
-        return newShardProps(newShardId(LOCAL_MEMBER_NAME), Collections.<String,String>emptyMap(), LOCAL_MEMBER_NAME);
-    }
-
-    private Props newShardProps(final ShardIdentifier shardId, final Map<String,String> peers,
-            final String memberName) {
-        return newShardProps(shardId, peers, memberName, EntityOwnerSelectionStrategyConfig.newBuilder().build());
-    }
-
-    private Props newShardProps(final ShardIdentifier shardId, final Map<String,String> peers, final String memberName,
-                                final EntityOwnerSelectionStrategyConfig config) {
-        return newShardBuilder(shardId, peers, memberName).ownerSelectionStrategyConfig(config).props()
-                    .withDispatcher(Dispatchers.DefaultDispatcherId());
-    }
-
-    private EntityOwnershipShard.Builder newShardBuilder(final ShardIdentifier shardId, final Map<String, String> peers,
-            final String memberName) {
-        return EntityOwnershipShard.newBuilder()
-                .id(shardId)
-                .peerAddresses(peers)
-                .datastoreContext(dataStoreContextBuilder.build())
-                .schemaContextProvider(() -> EOSTestUtils.SCHEMA_CONTEXT)
-                .localMemberName(MemberName.forName(memberName))
-                .ownerSelectionStrategyConfig(EntityOwnerSelectionStrategyConfig.newBuilder().build());
-    }
-
-    private Map<String, String> peerMap(final String... peerIds) {
-        ImmutableMap.Builder<String, String> builder = ImmutableMap.<String, String>builder();
-        for (String peerId: peerIds) {
-            builder.put(peerId, actorFactory.createTestActorPath(peerId)).build();
-        }
-
-        return builder.build();
-    }
-
-    private static class TestEntityOwnershipShard extends EntityOwnershipShard {
-        private final ActorRef collectorActor;
-        private final Map<Class<?>, Predicate<?>> dropMessagesOfType = new ConcurrentHashMap<>();
-
-        TestEntityOwnershipShard(final Builder builder, final ActorRef collectorActor) {
-            super(builder);
-            this.collectorActor = collectorActor;
-        }
-
-        @SuppressWarnings({ "unchecked", "rawtypes" })
-        @Override
-        public void handleCommand(final Object message) {
-            Predicate drop = dropMessagesOfType.get(message.getClass());
-            if (drop == null || !drop.test(message)) {
-                super.handleCommand(message);
-            }
-
-            if (collectorActor != null) {
-                collectorActor.tell(message, ActorRef.noSender());
-            }
-        }
-
-        void startDroppingMessagesOfType(final Class<?> msgClass) {
-            dropMessagesOfType.put(msgClass, msg -> true);
-        }
-
-        <T> void startDroppingMessagesOfType(final Class<T> msgClass, final Predicate<T> filter) {
-            dropMessagesOfType.put(msgClass, filter);
-        }
-
-        void stopDroppingMessagesOfType(final Class<?> msgClass) {
-            dropMessagesOfType.remove(msgClass);
-        }
-
-        ActorRef collectorActor() {
-            return collectorActor;
-        }
-
-        static Props props(final Builder builder) {
-            return props(builder, null);
-        }
-
-        static Props props(final Builder builder, final ActorRef collectorActor) {
-            return Props.create(TestEntityOwnershipShard.class, builder, collectorActor)
-                    .withDispatcher(Dispatchers.DefaultDispatcherId());
-        }
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/EntityOwnershipStatisticsTest.java b/opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/EntityOwnershipStatisticsTest.java
deleted file mode 100644 (file)
index 4ef77e5..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco 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.entityownership;
-
-import static org.junit.Assert.assertEquals;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.ENTITY_OWNERS_PATH;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.entityEntryWithOwner;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.entityOwnersWithCandidate;
-import static org.opendaylight.controller.cluster.entityownership.EntityOwnersModel.entityPath;
-
-import java.util.Map;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.opendaylight.controller.cluster.datastore.AbstractActorTest;
-import org.opendaylight.controller.cluster.datastore.Shard;
-import org.opendaylight.controller.cluster.datastore.ShardDataTree;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.TreeType;
-
-public class EntityOwnershipStatisticsTest extends AbstractActorTest {
-    private static final String LOCAL_MEMBER_NAME = "member-1";
-    private static final String REMOTE_MEMBER_NAME1 = "member-2";
-    private static final String REMOTE_MEMBER_NAME2 = "member-3";
-    private static final String ENTITY_TYPE = "test";
-    private static final YangInstanceIdentifier ENTITY_ID1 =
-            YangInstanceIdentifier.of(QName.create("test", "2015-08-14", "entity1"));
-    private static final YangInstanceIdentifier ENTITY_ID2 =
-            YangInstanceIdentifier.of(QName.create("test", "2015-08-14", "entity2"));
-
-    private final Shard mockShard = Mockito.mock(Shard.class);
-
-    private final ShardDataTree shardDataTree = new ShardDataTree(mockShard, EOSTestUtils.SCHEMA_CONTEXT,
-        TreeType.OPERATIONAL);
-    private EntityOwnershipStatistics ownershipStatistics;
-
-    @Before
-    public void setup() {
-        ownershipStatistics = new EntityOwnershipStatistics();
-        ownershipStatistics.init(shardDataTree);
-    }
-
-    @Test
-    public void testOnDataTreeChanged() throws Exception {
-        writeNode(ENTITY_OWNERS_PATH, entityOwnersWithCandidate(ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME));
-        writeNode(ENTITY_OWNERS_PATH, entityOwnersWithCandidate(ENTITY_TYPE, ENTITY_ID2, LOCAL_MEMBER_NAME));
-
-        // Write local member as owner for entity 1
-
-        writeNode(entityPath(ENTITY_TYPE, ENTITY_ID1), entityEntryWithOwner(ENTITY_ID1, LOCAL_MEMBER_NAME));
-        assertStatistics(ownershipStatistics.all(), LOCAL_MEMBER_NAME, 1L);
-
-        // Add remote member 1 as candidate for entity 1 - ownershipStatistics support should not get notified
-
-        writeNode(ENTITY_OWNERS_PATH, entityOwnersWithCandidate(ENTITY_TYPE, ENTITY_ID1, REMOTE_MEMBER_NAME1));
-        assertStatistics(ownershipStatistics.all(), LOCAL_MEMBER_NAME, 1L);
-
-        // Change owner to remote member 1 for entity 1
-
-        writeNode(entityPath(ENTITY_TYPE, ENTITY_ID1), entityEntryWithOwner(ENTITY_ID1, REMOTE_MEMBER_NAME1));
-        Map<String, Map<String, Long>> statistics = ownershipStatistics.all();
-        assertStatistics(statistics, LOCAL_MEMBER_NAME, 0L);
-        assertStatistics(statistics, REMOTE_MEMBER_NAME1, 1L);
-
-        // Change owner to remote member 2 for entity 1
-
-        writeNode(entityPath(ENTITY_TYPE, ENTITY_ID1), entityEntryWithOwner(ENTITY_ID1, REMOTE_MEMBER_NAME2));
-        statistics = ownershipStatistics.all();
-        assertStatistics(statistics, LOCAL_MEMBER_NAME, 0L);
-        assertStatistics(statistics, REMOTE_MEMBER_NAME1, 0L);
-        assertStatistics(statistics, REMOTE_MEMBER_NAME2, 1L);
-
-        // Clear the owner for entity 1
-
-        writeNode(entityPath(ENTITY_TYPE, ENTITY_ID1), entityEntryWithOwner(ENTITY_ID1, ""));
-        statistics = ownershipStatistics.all();
-        assertStatistics(statistics, LOCAL_MEMBER_NAME, 0L);
-        assertStatistics(statistics, REMOTE_MEMBER_NAME1, 0L);
-        assertStatistics(statistics, REMOTE_MEMBER_NAME2, 0L);
-
-        // Change owner to the local member for entity 1
-
-        writeNode(entityPath(ENTITY_TYPE, ENTITY_ID1), entityEntryWithOwner(ENTITY_ID1, LOCAL_MEMBER_NAME));
-        statistics = ownershipStatistics.all();
-        assertStatistics(statistics, LOCAL_MEMBER_NAME, 1L);
-        assertStatistics(statistics, REMOTE_MEMBER_NAME1, 0L);
-        assertStatistics(statistics, REMOTE_MEMBER_NAME2, 0L);
-
-        // Change owner to remote member 1 for entity 2
-
-        writeNode(entityPath(ENTITY_TYPE, ENTITY_ID2), entityEntryWithOwner(ENTITY_ID2, REMOTE_MEMBER_NAME1));
-        statistics = ownershipStatistics.all();
-        assertStatistics(statistics, LOCAL_MEMBER_NAME, 1L);
-        assertStatistics(statistics, REMOTE_MEMBER_NAME1, 1L);
-        assertStatistics(statistics, REMOTE_MEMBER_NAME2, 0L);
-
-        // Change owner to the local member for entity 2
-
-        writeNode(entityPath(ENTITY_TYPE, ENTITY_ID2), entityEntryWithOwner(ENTITY_ID2, LOCAL_MEMBER_NAME));
-        statistics = ownershipStatistics.all();
-        assertStatistics(statistics, LOCAL_MEMBER_NAME, 2L);
-        assertStatistics(statistics, REMOTE_MEMBER_NAME1, 0L);
-        assertStatistics(statistics, REMOTE_MEMBER_NAME2, 0L);
-
-        // Write local member owner for entity 2 again - expect no change
-        writeNode(entityPath(ENTITY_TYPE, ENTITY_ID2), entityEntryWithOwner(ENTITY_ID2, LOCAL_MEMBER_NAME));
-        statistics = ownershipStatistics.all();
-        assertStatistics(statistics, LOCAL_MEMBER_NAME, 2L);
-        assertStatistics(statistics, REMOTE_MEMBER_NAME1, 0L);
-        assertStatistics(statistics, REMOTE_MEMBER_NAME2, 0L);
-
-        // Clear the owner for entity 2
-        writeNode(entityPath(ENTITY_TYPE, ENTITY_ID2), entityEntryWithOwner(ENTITY_ID2, ""));
-        statistics = ownershipStatistics.all();
-        assertStatistics(statistics, LOCAL_MEMBER_NAME, 1L);
-        assertStatistics(statistics, REMOTE_MEMBER_NAME1, 0L);
-        assertStatistics(statistics, REMOTE_MEMBER_NAME2, 0L);
-
-        // Clear the owner for entity 2 again - expect no change
-
-        writeNode(entityPath(ENTITY_TYPE, ENTITY_ID2), entityEntryWithOwner(ENTITY_ID2, ""));
-        statistics = ownershipStatistics.all();
-        assertStatistics(statistics, LOCAL_MEMBER_NAME, 1L);
-        assertStatistics(statistics, REMOTE_MEMBER_NAME1, 0L);
-        assertStatistics(statistics, REMOTE_MEMBER_NAME2, 0L);
-
-    }
-
-    private static void assertStatistics(final Map<String, Map<String, Long>> statistics, final String memberName,
-            final long val) {
-        assertEquals(val, statistics.get(ENTITY_TYPE).get(memberName).longValue());
-    }
-
-    private void writeNode(final YangInstanceIdentifier path, final NormalizedNode node)
-            throws DataValidationFailedException {
-        AbstractEntityOwnershipTest.writeNode(path, node, shardDataTree);
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/selectionstrategy/EntityOwnerSelectionStrategyConfigReaderTest.java b/opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/selectionstrategy/EntityOwnerSelectionStrategyConfigReaderTest.java
deleted file mode 100644 (file)
index b83f85e..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco 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.entityownership.selectionstrategy;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import org.junit.Test;
-
-public class EntityOwnerSelectionStrategyConfigReaderTest {
-
-    @Test
-    public void testReadStrategies() {
-        final Map<Object, Object> props = new java.util.HashMap<>();
-        props.put("entity.type.test",
-            "org.opendaylight.controller.cluster.entityownership.selectionstrategy.LastCandidateSelectionStrategy,100");
-
-
-        final EntityOwnerSelectionStrategyConfig config = EntityOwnerSelectionStrategyConfigReader
-                .loadStrategyWithConfig(props);
-
-        assertTrue(config.isStrategyConfigured("test"));
-
-        final EntityOwnerSelectionStrategy strategy = config.createStrategy("test",
-                Collections.<String, Long>emptyMap());
-        assertTrue(strategy.toString(), strategy instanceof LastCandidateSelectionStrategy);
-        assertEquals(100L, strategy.getSelectionDelayInMillis());
-
-        final EntityOwnerSelectionStrategy strategy1 = config.createStrategy("test", Collections.emptyMap());
-        assertEquals(strategy, strategy1);
-
-        config.clearStrategies();
-
-        final EntityOwnerSelectionStrategy strategy2 = config.createStrategy("test", Collections.emptyMap());
-        assertNotEquals(strategy1, strategy2);
-    }
-
-    @Test
-    public void testReadStrategiesWithEmptyConfiguration() {
-
-        final Map<Object, Object> props = new HashMap<>();
-        final EntityOwnerSelectionStrategyConfig config = EntityOwnerSelectionStrategyConfigReader
-                .loadStrategyWithConfig(props);
-
-        assertFalse(config.isStrategyConfigured("test"));
-    }
-
-    @Test
-    public void testReadStrategiesWithNullConfiguration() {
-        final EntityOwnerSelectionStrategyConfig config = EntityOwnerSelectionStrategyConfigReader
-                .loadStrategyWithConfig(null);
-        assertFalse(config.isStrategyConfigured("test"));
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testReadStrategiesInvalidDelay() {
-        final Map<Object, Object> props = new HashMap<>();
-        props.put("entity.type.test",
-            "org.opendaylight.controller.cluster.entityownership.selectionstrategy.LastCandidateSelectionStrategy,foo");
-        EntityOwnerSelectionStrategyConfigReader.loadStrategyWithConfig(props);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testReadStrategiesInvalidClassType() {
-        final Map<Object, Object> props = new HashMap<>();
-        props.put("entity.type.test", "String,100");
-        EntityOwnerSelectionStrategyConfigReader.loadStrategyWithConfig(props);
-    }
-
-    @Test
-    public void testReadStrategiesMissingDelay() {
-        final Map<Object, Object> props = new HashMap<>();
-        props.put("entity.type.test",
-            "org.opendaylight.controller.cluster.entityownership.selectionstrategy.LastCandidateSelectionStrategy,100");
-        props.put("entity.type.test1",
-            "org.opendaylight.controller.cluster.entityownership.selectionstrategy.LastCandidateSelectionStrategy");
-
-
-        final EntityOwnerSelectionStrategyConfig config = EntityOwnerSelectionStrategyConfigReader
-                .loadStrategyWithConfig(props);
-
-        assertEquals(100, config.createStrategy("test", Collections.emptyMap()).getSelectionDelayInMillis());
-        assertEquals(0, config.createStrategy("test2", Collections.emptyMap()).getSelectionDelayInMillis());
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/selectionstrategy/LastCandidateSelectionStrategy.java b/opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/selectionstrategy/LastCandidateSelectionStrategy.java
deleted file mode 100644 (file)
index 07d6f63..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco 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.entityownership.selectionstrategy;
-
-import com.google.common.collect.Iterables;
-import java.util.Collection;
-import java.util.Map;
-
-public class LastCandidateSelectionStrategy extends AbstractEntityOwnerSelectionStrategy {
-    public LastCandidateSelectionStrategy(long selectionDelayInMillis, Map<String, Long> initialStatistics) {
-        super(selectionDelayInMillis, initialStatistics);
-    }
-
-    @Override
-    public String newOwner(String currentOwner, Collection<String> viableCandidates) {
-        return Iterables.getLast(viableCandidates);
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/selectionstrategy/LeastLoadedCandidateSelectionStrategyTest.java b/opendaylight/md-sal/sal-distributed-eos/src/test/java/org/opendaylight/controller/cluster/entityownership/selectionstrategy/LeastLoadedCandidateSelectionStrategyTest.java
deleted file mode 100644 (file)
index 7362840..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco 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.entityownership.selectionstrategy;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import org.junit.Test;
-
-public class LeastLoadedCandidateSelectionStrategyTest {
-
-    @Test
-    public void testLeastLoadedStrategy() {
-        LeastLoadedCandidateSelectionStrategy strategy = new LeastLoadedCandidateSelectionStrategy(
-                0L, Collections.<String, Long>emptyMap());
-
-        String owner = strategy.newOwner(null, prepareViableCandidates(3));
-        assertEquals("member-1", owner);
-
-        Map<String, Long> localStatistics = strategy.getLocalStatistics();
-        assertEquals(1L, (long) localStatistics.get("member-1"));
-
-        // member-2 has least load
-        strategy = new LeastLoadedCandidateSelectionStrategy(0L, prepareStatistics(5,2,4));
-        owner = strategy.newOwner(null, prepareViableCandidates(3));
-        assertEquals("member-2", owner);
-
-        assertStatistics(strategy.getLocalStatistics(), 5,3,4);
-
-        // member-3 has least load
-        strategy = new LeastLoadedCandidateSelectionStrategy(0L, prepareStatistics(5,7,4));
-        owner = strategy.newOwner(null, prepareViableCandidates(3));
-        assertEquals("member-3", owner);
-
-        assertStatistics(strategy.getLocalStatistics(), 5,7,5);
-
-        // member-1 has least load
-        strategy = new LeastLoadedCandidateSelectionStrategy(0L, prepareStatistics(1,7,4));
-        owner = strategy.newOwner(null, prepareViableCandidates(3));
-        assertEquals("member-1", owner);
-
-        assertStatistics(strategy.getLocalStatistics(), 2,7,4);
-
-        // Let member-3 become the owner
-        strategy = new LeastLoadedCandidateSelectionStrategy(0L, prepareStatistics(3,3,0));
-        owner = strategy.newOwner(null, prepareViableCandidates(3));
-        assertEquals("member-3", owner);
-
-        assertStatistics(strategy.getLocalStatistics(), 3,3,1);
-
-        // member-3 is no longer viable so choose a new owner
-        owner = strategy.newOwner("member-3", prepareViableCandidates(2));
-        assertEquals("member-1", owner);
-
-        assertStatistics(strategy.getLocalStatistics(), 4,3,0);
-
-    }
-
-    private static Map<String, Long> prepareStatistics(long... count) {
-        Map<String, Long> statistics = new HashMap<>();
-        for (int i = 0; i < count.length; i++) {
-            statistics.put("member-" + (i + 1), count[i]);
-        }
-        return statistics;
-    }
-
-    private static Collection<String> prepareViableCandidates(int count) {
-        Collection<String> viableCandidates = new ArrayList<>();
-        for (int i = 0; i < count; i++) {
-            viableCandidates.add("member-" + (i + 1));
-        }
-        return viableCandidates;
-    }
-
-    private static void assertStatistics(Map<String, Long> statistics, long... count) {
-        for (int i = 0; i < count.length; i++) {
-            assertEquals(count[i], (long) statistics.get("member-" + (i + 1)));
-        }
-    }
-}