Bug 4105: Remove EntityOwnershipCandidate 50/26950/2
authorTom Pantelis <tpanteli@brocade.com>
Fri, 11 Sep 2015 20:13:24 +0000 (16:13 -0400)
committerGerrit Code Review <gerrit@opendaylight.org>
Tue, 15 Sep 2015 14:54:03 +0000 (14:54 +0000)
It was decided that we really don't need to pass an
EntityOwnershipCandidate listener when registering a candidate. Since
apps would most likely create a singleton EntityOwnershipCandidate for
all registerCandidate calls, they might as well register the singleton
listener once via registerListener. This simplifies the interface and
also simplifies OF clustering b/c they need an EntityOwnershipListener
anyway for device node cleanup.

Change-Id: I9fb7d68c1ffbf932c9d0e18efef604c1b05fdf96
Signed-off-by: Tom Pantelis <tpanteli@brocade.com>
(cherry picked from commit 6b0f9975b09044b7c3c8877ae2d2d06f0a29894a)

16 files changed:
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/clustering/CandidateAlreadyRegisteredException.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/clustering/EntityOwnershipCandidate.java [deleted file]
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/clustering/EntityOwnershipCandidateRegistration.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/clustering/EntityOwnershipService.java
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/clustering/AbstractEntityOwnershipCandidateRegistration.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/entityownership/DistributedEntityOwnershipCandidateRegistration.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/entityownership/DistributedEntityOwnershipService.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/entityownership/EntityOwnershipListenerSupport.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/entityownership/EntityOwnershipShard.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/entityownership/messages/RegisterCandidateLocal.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/entityownership/messages/UnregisterCandidateLocal.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/entityownership/DistributedEntityOwnershipIntegrationTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/entityownership/DistributedEntityOwnershipServiceTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/entityownership/EntityOwnershipListenerSupportTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/entityownership/EntityOwnershipShardTest.java
opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/CarProvider.java

index 7e35bc9439a134780c9b8e8a617c07eb0aa5166a..976688946fa65b34e566ad51022a52b91b313bbb 100644 (file)
@@ -19,15 +19,11 @@ public class CandidateAlreadyRegisteredException extends Exception {
     private static final long serialVersionUID = 1L;
 
     private final Entity entity;
     private static final long serialVersionUID = 1L;
 
     private final Entity entity;
-    private final EntityOwnershipCandidate registeredCandidate;
 
 
-    public CandidateAlreadyRegisteredException(@Nonnull Entity entity,
-                                               @Nonnull EntityOwnershipCandidate registeredCandidate) {
-        super(String.format("Candidate %s has already been registered for %s",
-                Preconditions.checkNotNull(registeredCandidate, "registeredCandidate should not be null"),
+    public CandidateAlreadyRegisteredException(@Nonnull Entity entity) {
+        super(String.format("Candidate has already been registered for %s",
                 Preconditions.checkNotNull(entity, "entity should not be null")));
         this.entity = entity;
                 Preconditions.checkNotNull(entity, "entity should not be null")));
         this.entity = entity;
-        this.registeredCandidate = registeredCandidate;
     }
 
     /**
     }
 
     /**
@@ -38,13 +34,4 @@ public class CandidateAlreadyRegisteredException extends Exception {
     public Entity getEntity() {
         return entity;
     }
     public Entity getEntity() {
         return entity;
     }
-
-    /**
-     *
-     * @return the currently registered candidate
-     */
-    @Nonnull
-    public EntityOwnershipCandidate getRegisteredCandidate() {
-        return registeredCandidate;
-    }
 }
 }
diff --git a/opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/clustering/EntityOwnershipCandidate.java b/opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/clustering/EntityOwnershipCandidate.java
deleted file mode 100644 (file)
index 085b4fb..0000000
+++ /dev/null
@@ -1,18 +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.md.sal.common.api.clustering;
-
-/**
- * <p>
- * An EntityOwnershipCandidate represents a component which would like to own a given Entity.
- * The EntityOwnershipCandidate will be notified of changes in ownership as it is also an EntityOwnershipListener.
- * </p>
- */
-public interface EntityOwnershipCandidate extends EntityOwnershipListener {
-}
index c3c43d92ba481c963cc91a257e7b6fa259b5c778..e59aefb9c4c6ccf30eed8c03d77af2cce8ecf3c4 100644 (file)
@@ -8,22 +8,16 @@
 
 package org.opendaylight.controller.md.sal.common.api.clustering;
 
 
 package org.opendaylight.controller.md.sal.common.api.clustering;
 
-import javax.annotation.Nonnull;
 import org.opendaylight.yangtools.concepts.ObjectRegistration;
 
 /**
  * An EntityOwnershipCandidateRegistration records a request to register a Candidate for a given Entity. Calling
  * close on the EntityOwnershipCandidateRegistration will remove the Candidate from any future ownership considerations
 import org.opendaylight.yangtools.concepts.ObjectRegistration;
 
 /**
  * An EntityOwnershipCandidateRegistration records a request to register a Candidate for a given Entity. Calling
  * close on the EntityOwnershipCandidateRegistration will remove the Candidate from any future ownership considerations
- * for that Entity and will also remove it as a Listener for ownership status changes.
+ * for that Entity.
  */
  */
-public interface EntityOwnershipCandidateRegistration extends ObjectRegistration<EntityOwnershipCandidate> {
+public interface EntityOwnershipCandidateRegistration extends ObjectRegistration<Entity> {
    /**
    /**
-    * Returns the entity that the listener was registered for
-    */
-    @Nonnull Entity getEntity();
-
-   /**
-    * Unregister the listener
+    * Unregister the candidate
     */
    @Override
    void close();
     */
    @Override
    void close();
index 52009a2374b564da79ca277945a2fa72a5da9c0e..f200f5adc1cc7ddebc613126ef4030773fba3521 100644 (file)
@@ -28,17 +28,14 @@ public interface EntityOwnershipService {
      * per process. If multiple requests for registering a candidate for a given entity are received in the
      * current process a CandidateAlreadyRegisteredException will be thrown.
      * <p>
      * per process. If multiple requests for registering a candidate for a given entity are received in the
      * current process a CandidateAlreadyRegisteredException will be thrown.
      * <p>
-     * The registration is performed asynchronously and the {@link EntityOwnershipCandidate} instance is
-     * notified whenever its process instance is granted ownership of the entity and also whenever it loses
-     * ownership. Note that the {@link EntityOwnershipCandidate} is not notified when another process instance
-     * is granted ownership.
+     * The registration is performed asynchronously and any registered {@link EntityOwnershipListener} is
+     * notified of ownership status changes for the entity.
      *
      * @param entity the entity which the Candidate wants to own
      *
      * @param entity the entity which the Candidate wants to own
-     * @param candidate the Candidate that wants to own the entity
      * @return a registration object that can be used to unregister the Candidate
      * @throws org.opendaylight.controller.md.sal.common.api.clustering.CandidateAlreadyRegisteredException
      */
      * @return a registration object that can be used to unregister the Candidate
      * @throws org.opendaylight.controller.md.sal.common.api.clustering.CandidateAlreadyRegisteredException
      */
-    EntityOwnershipCandidateRegistration registerCandidate(@Nonnull Entity entity, @Nonnull EntityOwnershipCandidate candidate)
+    EntityOwnershipCandidateRegistration registerCandidate(@Nonnull Entity entity)
             throws CandidateAlreadyRegisteredException;
 
     /**
             throws CandidateAlreadyRegisteredException;
 
     /**
index afef3aa8b5e873bfffbbf5234140da61c496d411..a0f41c7d836eaef0729df0fad7ff7946a803a932 100644 (file)
@@ -10,7 +10,6 @@ package org.opendaylight.controller.md.sal.common.impl.clustering;
 import com.google.common.base.Preconditions;
 import javax.annotation.Nonnull;
 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
 import com.google.common.base.Preconditions;
 import javax.annotation.Nonnull;
 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidate;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidateRegistration;
 import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
 
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidateRegistration;
 import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
 
@@ -19,18 +18,10 @@ import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
  *
  * @author Thomas Pantelis
  */
  *
  * @author Thomas Pantelis
  */
-public abstract class AbstractEntityOwnershipCandidateRegistration extends AbstractObjectRegistration<EntityOwnershipCandidate>
+public abstract class AbstractEntityOwnershipCandidateRegistration extends AbstractObjectRegistration<Entity>
         implements EntityOwnershipCandidateRegistration {
         implements EntityOwnershipCandidateRegistration {
-    private final Entity entity;
 
 
-    protected AbstractEntityOwnershipCandidateRegistration(@Nonnull EntityOwnershipCandidate candidate,
-            @Nonnull Entity entity) {
-        super(candidate);
-        this.entity = Preconditions.checkNotNull(entity, "entity cannot be null");
-    }
-
-    @Override
-    public Entity getEntity() {
-        return entity;
+    protected AbstractEntityOwnershipCandidateRegistration(@Nonnull Entity entity) {
+        super(Preconditions.checkNotNull(entity, "entity cannot be null"));
     }
 }
     }
 }
index b92a124b2831adb2a224122db29cdfac6d4d353c..0492cbcc72b6c6a3be7bae1bbc995927aa49a189 100644 (file)
@@ -8,7 +8,6 @@
 package org.opendaylight.controller.cluster.datastore.entityownership;
 
 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
 package org.opendaylight.controller.cluster.datastore.entityownership;
 
 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidate;
 import org.opendaylight.controller.md.sal.common.impl.clustering.AbstractEntityOwnershipCandidateRegistration;
 
 /**
 import org.opendaylight.controller.md.sal.common.impl.clustering.AbstractEntityOwnershipCandidateRegistration;
 
 /**
@@ -19,21 +18,19 @@ import org.opendaylight.controller.md.sal.common.impl.clustering.AbstractEntityO
 class DistributedEntityOwnershipCandidateRegistration extends AbstractEntityOwnershipCandidateRegistration {
     private final DistributedEntityOwnershipService service;
 
 class DistributedEntityOwnershipCandidateRegistration extends AbstractEntityOwnershipCandidateRegistration {
     private final DistributedEntityOwnershipService service;
 
-    DistributedEntityOwnershipCandidateRegistration(EntityOwnershipCandidate candidate, Entity entity,
-            DistributedEntityOwnershipService service) {
-        super(candidate, entity);
+    DistributedEntityOwnershipCandidateRegistration(Entity entity, DistributedEntityOwnershipService service) {
+        super(entity);
         this.service = service;
     }
 
     @Override
     protected void removeRegistration() {
         this.service = service;
     }
 
     @Override
     protected void removeRegistration() {
-        service.unregisterCandidate(getEntity(), getInstance());
+        service.unregisterCandidate(getInstance());
     }
 
     @Override
     public String toString() {
     }
 
     @Override
     public String toString() {
-        return "DistributedEntityOwnershipCandidateRegistration [entity=" + getEntity() + ", candidate="
-                + getInstance() + "]";
+        return "DistributedEntityOwnershipCandidateRegistration [entity=" + getInstance() + "]";
     }
 
 
     }
 
 
index cd45ef58a9660c331aae11c1f691b62580039b2f..e272b80a67893ba927f42099c090e1817ce77282 100644 (file)
@@ -27,7 +27,6 @@ import org.opendaylight.controller.cluster.datastore.messages.CreateShard;
 import org.opendaylight.controller.cluster.datastore.shardstrategy.ModuleShardStrategy;
 import org.opendaylight.controller.md.sal.common.api.clustering.CandidateAlreadyRegisteredException;
 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
 import org.opendaylight.controller.cluster.datastore.shardstrategy.ModuleShardStrategy;
 import org.opendaylight.controller.md.sal.common.api.clustering.CandidateAlreadyRegisteredException;
 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidate;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidateRegistration;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidateRegistration;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration;
@@ -48,7 +47,7 @@ public class DistributedEntityOwnershipService implements EntityOwnershipService
     private static final Timeout MESSAGE_TIMEOUT = new Timeout(1, TimeUnit.MINUTES);
 
     private final DistributedDataStore datastore;
     private static final Timeout MESSAGE_TIMEOUT = new Timeout(1, TimeUnit.MINUTES);
 
     private final DistributedDataStore datastore;
-    private final ConcurrentMap<Entity, EntityOwnershipCandidate> registeredEntities = new ConcurrentHashMap<>();
+    private final ConcurrentMap<Entity, Entity> registeredEntities = new ConcurrentHashMap<>();
     private volatile ActorRef localEntityOwnershipShard;
 
     public DistributedEntityOwnershipService(DistributedDataStore datastore) {
     private volatile ActorRef localEntityOwnershipShard;
 
     public DistributedEntityOwnershipService(DistributedDataStore datastore) {
@@ -114,28 +113,26 @@ public class DistributedEntityOwnershipService implements EntityOwnershipService
     }
 
     @Override
     }
 
     @Override
-    public EntityOwnershipCandidateRegistration registerCandidate(Entity entity, EntityOwnershipCandidate candidate)
+    public EntityOwnershipCandidateRegistration registerCandidate(Entity entity)
             throws CandidateAlreadyRegisteredException {
         Preconditions.checkNotNull(entity, "entity cannot be null");
             throws CandidateAlreadyRegisteredException {
         Preconditions.checkNotNull(entity, "entity cannot be null");
-        Preconditions.checkNotNull(candidate, "candidate cannot be null");
 
 
-        EntityOwnershipCandidate currentCandidate = registeredEntities.putIfAbsent(entity, candidate);
-        if(currentCandidate != null) {
-            throw new CandidateAlreadyRegisteredException(entity, currentCandidate);
+        if(registeredEntities.putIfAbsent(entity, entity) != null) {
+            throw new CandidateAlreadyRegisteredException(entity);
         }
 
         }
 
-        RegisterCandidateLocal registerCandidate = new RegisterCandidateLocal(candidate, entity);
+        RegisterCandidateLocal registerCandidate = new RegisterCandidateLocal(entity);
 
         LOG.debug("Registering candidate with message: {}", registerCandidate);
 
         executeLocalEntityOwnershipShardOperation(registerCandidate);
 
         LOG.debug("Registering candidate with message: {}", registerCandidate);
 
         executeLocalEntityOwnershipShardOperation(registerCandidate);
-        return new DistributedEntityOwnershipCandidateRegistration(candidate, entity, this);
+        return new DistributedEntityOwnershipCandidateRegistration(entity, this);
     }
 
     }
 
-    void unregisterCandidate(Entity entity, EntityOwnershipCandidate entityOwnershipCandidate) {
-        LOG.debug("Unregistering candidate {} for {}", entityOwnershipCandidate, entity);
+    void unregisterCandidate(Entity entity) {
+        LOG.debug("Unregistering candidate for {}", entity);
 
 
-        executeLocalEntityOwnershipShardOperation(new UnregisterCandidateLocal(entityOwnershipCandidate, entity));
+        executeLocalEntityOwnershipShardOperation(new UnregisterCandidateLocal(entity));
         registeredEntities.remove(entity);
     }
 
         registeredEntities.remove(entity);
     }
 
index a09d224954aedcbde762045d9d9e51c61a5bf7f6..e944325c69229ade6828dca233043c307b43f6eb 100644 (file)
@@ -14,10 +14,11 @@ import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Multimap;
 import java.util.Arrays;
 import java.util.Collection;
 import com.google.common.collect.Multimap;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.IdentityHashMap;
 import java.util.Map;
 import java.util.IdentityHashMap;
 import java.util.Map;
+import java.util.Set;
 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidate;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipChange;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
 import org.slf4j.Logger;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipChange;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
 import org.slf4j.Logger;
@@ -34,7 +35,7 @@ class EntityOwnershipListenerSupport {
     private final String logId;
     private final ActorContext actorContext;
     private final Map<EntityOwnershipListener, ListenerActorRefEntry> listenerActorMap = new IdentityHashMap<>();
     private final String logId;
     private final ActorContext actorContext;
     private final Map<EntityOwnershipListener, ListenerActorRefEntry> listenerActorMap = new IdentityHashMap<>();
-    private final Multimap<Entity, EntityOwnershipListener> entityListenerMap = HashMultimap.create();
+    private final Set<Entity> entitiesWithCandidateSet = new HashSet<>();
     private final Multimap<String, EntityOwnershipListener> entityTypeListenerMap = HashMultimap.create();
 
     EntityOwnershipListenerSupport(ActorContext actorContext, String logId) {
     private final Multimap<String, EntityOwnershipListener> entityTypeListenerMap = HashMultimap.create();
 
     EntityOwnershipListenerSupport(ActorContext actorContext, String logId) {
@@ -47,19 +48,15 @@ class EntityOwnershipListenerSupport {
     }
 
     boolean hasCandidateForEntity(Entity entity) {
     }
 
     boolean hasCandidateForEntity(Entity entity) {
-        for(EntityOwnershipListener listener: entityListenerMap.get(entity)) {
-            if(listener instanceof EntityOwnershipCandidate) {
-                return true;
-            }
-        }
-
-        return false;
+        return entitiesWithCandidateSet.contains(entity);
     }
 
     }
 
-    void addEntityOwnershipListener(Entity entity, EntityOwnershipListener listener) {
-        LOG.debug("{}: Adding EntityOwnershipListener {} for {}", logId, listener, entity);
+    void setHasCandidateForEntity(Entity entity) {
+        entitiesWithCandidateSet.add(entity);
+    }
 
 
-        addListener(listener, entity, entityListenerMap);
+    void unsetHasCandidateForEntity(Entity entity) {
+        entitiesWithCandidateSet.remove(entity);
     }
 
     void addEntityOwnershipListener(String entityType, EntityOwnershipListener listener) {
     }
 
     void addEntityOwnershipListener(String entityType, EntityOwnershipListener listener) {
@@ -68,12 +65,6 @@ class EntityOwnershipListenerSupport {
         addListener(listener, entityType, entityTypeListenerMap);
     }
 
         addListener(listener, entityType, entityTypeListenerMap);
     }
 
-    void removeEntityOwnershipListener(Entity entity, EntityOwnershipListener listener) {
-        LOG.debug("{}: Removing EntityOwnershipListener {} for {}", logId, listener, entity);
-
-        removeListener(listener, entity, entityListenerMap);
-    }
-
     void removeEntityOwnershipListener(String entityType, EntityOwnershipListener listener) {
         LOG.debug("{}: Removing EntityOwnershipListener {} for entity type {}", logId, listener, entityType);
 
     void removeEntityOwnershipListener(String entityType, EntityOwnershipListener listener) {
         LOG.debug("{}: Removing EntityOwnershipListener {} for entity type {}", logId, listener, entityType);
 
@@ -81,7 +72,6 @@ class EntityOwnershipListenerSupport {
     }
 
     void notifyEntityOwnershipListeners(Entity entity, boolean wasOwner, boolean isOwner, boolean hasOwner) {
     }
 
     void notifyEntityOwnershipListeners(Entity entity, boolean wasOwner, boolean isOwner, boolean hasOwner) {
-        notifyListeners(entity, entity, wasOwner, isOwner, hasOwner, entityListenerMap);
         notifyListeners(entity, entity.getType(), wasOwner, isOwner, hasOwner, entityTypeListenerMap);
     }
 
         notifyListeners(entity, entity.getType(), wasOwner, isOwner, hasOwner, entityTypeListenerMap);
     }
 
index d8b1b5324487d10508829b8469fec6ffc9beb97c..1641b668c325804e1680cd3089f95a83e91c2d7b 100644 (file)
@@ -132,7 +132,7 @@ class EntityOwnershipShard extends Shard {
     private void onRegisterCandidateLocal(RegisterCandidateLocal registerCandidate) {
         LOG.debug("{}: onRegisterCandidateLocal: {}", persistenceId(), registerCandidate);
 
     private void onRegisterCandidateLocal(RegisterCandidateLocal registerCandidate) {
         LOG.debug("{}: onRegisterCandidateLocal: {}", persistenceId(), registerCandidate);
 
-        listenerSupport.addEntityOwnershipListener(registerCandidate.getEntity(), registerCandidate.getCandidate());
+        listenerSupport.setHasCandidateForEntity(registerCandidate.getEntity());
 
         NormalizedNode<?, ?> entityOwners = entityOwnersWithCandidate(registerCandidate.getEntity().getType(),
                 registerCandidate.getEntity().getId(), localMemberName);
 
         NormalizedNode<?, ?> entityOwners = entityOwnersWithCandidate(registerCandidate.getEntity().getType(),
                 registerCandidate.getEntity().getId(), localMemberName);
@@ -145,7 +145,7 @@ class EntityOwnershipShard extends Shard {
         LOG.debug("{}: onUnregisterCandidateLocal: {}", persistenceId(), unregisterCandidate);
 
         Entity entity = unregisterCandidate.getEntity();
         LOG.debug("{}: onUnregisterCandidateLocal: {}", persistenceId(), unregisterCandidate);
 
         Entity entity = unregisterCandidate.getEntity();
-        listenerSupport.removeEntityOwnershipListener(entity, unregisterCandidate.getCandidate());
+        listenerSupport.unsetHasCandidateForEntity(entity);
 
         YangInstanceIdentifier candidatePath = candidatePath(entity.getType(), entity.getId(), localMemberName);
         commitCoordinator.commitModification(new DeleteModification(candidatePath), this);
 
         YangInstanceIdentifier candidatePath = candidatePath(entity.getType(), entity.getId(), localMemberName);
         commitCoordinator.commitModification(new DeleteModification(candidatePath), this);
index 72c95e0c23abdccb8709fea0d522996fb39885b3..8b15aa2b3b09321ffaa9f97c228b40287d6178ef 100644 (file)
@@ -8,7 +8,6 @@
 package org.opendaylight.controller.cluster.datastore.entityownership.messages;
 
 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
 package org.opendaylight.controller.cluster.datastore.entityownership.messages;
 
 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidate;
 
 /**
  * Message sent to the local EntityOwnershipShard to register a candidate.
 
 /**
  * Message sent to the local EntityOwnershipShard to register a candidate.
@@ -16,27 +15,18 @@ import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipC
  * @author Thomas Pantelis
  */
 public class RegisterCandidateLocal {
  * @author Thomas Pantelis
  */
 public class RegisterCandidateLocal {
-    private final EntityOwnershipCandidate candidate;
     private final Entity entity;
 
     private final Entity entity;
 
-    public RegisterCandidateLocal(EntityOwnershipCandidate candidate, Entity entity) {
-        this.candidate = candidate;
+    public RegisterCandidateLocal(Entity entity) {
         this.entity = entity;
     }
 
         this.entity = entity;
     }
 
-    public EntityOwnershipCandidate getCandidate() {
-        return candidate;
-    }
-
     public Entity getEntity() {
         return entity;
     }
 
     @Override
     public String toString() {
     public Entity getEntity() {
         return entity;
     }
 
     @Override
     public String toString() {
-        StringBuilder builder = new StringBuilder();
-        builder.append("RegisterCandidateLocal [entity=").append(entity).append(", candidate=").append(candidate)
-                .append("]");
-        return builder.toString();
+        return "RegisterCandidateLocal [entity=" + entity + "]";
     }
 }
     }
 }
index 04d7960b7faafe5bc715c440a42eae9aaa5c2778..3373564c67f318d8cfec4fef479af4419f139ff7 100644 (file)
@@ -8,7 +8,6 @@
 package org.opendaylight.controller.cluster.datastore.entityownership.messages;
 
 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
 package org.opendaylight.controller.cluster.datastore.entityownership.messages;
 
 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidate;
 
 /**
  * Message sent to the local EntityOwnershipShard to unregister a candidate.
 
 /**
  * Message sent to the local EntityOwnershipShard to unregister a candidate.
@@ -16,24 +15,18 @@ import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipC
  * @author Thomas Pantelis
  */
 public class UnregisterCandidateLocal {
  * @author Thomas Pantelis
  */
 public class UnregisterCandidateLocal {
-    private final EntityOwnershipCandidate candidate;
     private final Entity entity;
 
     private final Entity entity;
 
-    public UnregisterCandidateLocal(EntityOwnershipCandidate candidate, Entity entity) {
-        this.candidate = candidate;
+    public UnregisterCandidateLocal(Entity entity) {
         this.entity = entity;
     }
 
         this.entity = entity;
     }
 
-    public EntityOwnershipCandidate getCandidate() {
-        return candidate;
-    }
-
     public Entity getEntity() {
         return entity;
     }
 
     @Override
     public String toString() {
     public Entity getEntity() {
         return entity;
     }
 
     @Override
     public String toString() {
-        return "UnregisterCandidateLocal [entity=" + entity + ", candidate=" + candidate + "]";
+        return "UnregisterCandidateLocal [entity=" + entity + "]";
     }
 }
     }
 }
index ed7ca2d33e3ce5a0f79f4b4894a183ceaf722b6d..990769e017eac4df6271d8714328e1a9b65b8dd3 100644 (file)
@@ -38,7 +38,7 @@ import org.opendaylight.controller.cluster.datastore.DistributedDataStore;
 import org.opendaylight.controller.cluster.datastore.IntegrationTestKit;
 import org.opendaylight.controller.md.cluster.datastore.model.SchemaContextHelper;
 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
 import org.opendaylight.controller.cluster.datastore.IntegrationTestKit;
 import org.opendaylight.controller.md.cluster.datastore.model.SchemaContextHelper;
 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidate;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
 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.schema.MapEntryNode;
 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.schema.MapEntryNode;
@@ -84,25 +84,16 @@ public class DistributedEntityOwnershipIntegrationTest {
     private IntegrationTestKit follower2TestKit;
 
     @Mock
     private IntegrationTestKit follower2TestKit;
 
     @Mock
-    private EntityOwnershipCandidate leaderMockCandidate;
+    private EntityOwnershipListener leaderMockListener;
 
     @Mock
 
     @Mock
-    private EntityOwnershipCandidate follower1MockCandidate;
+    private EntityOwnershipListener leaderMockListener2;
 
     @Mock
 
     @Mock
-    private EntityOwnershipCandidate follower2MockCandidate;
+    private EntityOwnershipListener follower1MockListener;
 
     @Mock
 
     @Mock
-    private EntityOwnershipCandidate leaderMockListener;
-
-    @Mock
-    private EntityOwnershipCandidate leaderMockListener2;
-
-    @Mock
-    private EntityOwnershipCandidate follower1MockListener;
-
-    @Mock
-    private EntityOwnershipCandidate follower2MockListener;
+    private EntityOwnershipListener follower2MockListener;
 
     @Before
     public void setUp() {
 
     @Before
     public void setUp() {
@@ -165,21 +156,21 @@ public class DistributedEntityOwnershipIntegrationTest {
 
         // Register leader candidate for entity1 and verify it becomes owner
 
 
         // Register leader candidate for entity1 and verify it becomes owner
 
-        leaderEntityOwnershipService.registerCandidate(ENTITY1, leaderMockCandidate);
+        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);
 
         // Register leader candidate for entity1_2 (same id, different type) and verify it becomes owner
 
         verify(leaderMockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY1, false, true, true));
         verify(follower1MockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY1, false, false, true));
         reset(leaderMockListener, follower1MockListener);
 
         // Register leader candidate for entity1_2 (same id, different type) and verify it becomes owner
 
-        leaderEntityOwnershipService.registerCandidate(ENTITY1_2, leaderMockCandidate);
+        leaderEntityOwnershipService.registerCandidate(ENTITY1_2);
         verify(leaderMockListener2, timeout(5000)).ownershipChanged(ownershipChange(ENTITY1_2, false, true, true));
         verify(leaderMockListener, timeout(300).never()).ownershipChanged(ownershipChange(ENTITY1_2));
         reset(leaderMockListener2);
 
         // Register follower1 candidate for entity1 and verify it gets added but doesn't become owner
 
         verify(leaderMockListener2, timeout(5000)).ownershipChanged(ownershipChange(ENTITY1_2, false, true, true));
         verify(leaderMockListener, timeout(300).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, follower1MockCandidate);
+        follower1EntityOwnershipService.registerCandidate(ENTITY1);
         verifyCandidates(leaderDistributedDataStore, ENTITY1, "member-1", "member-2");
         verifyOwner(leaderDistributedDataStore, ENTITY1, "member-1");
         verify(leaderMockListener, timeout(300).never()).ownershipChanged(ownershipChange(ENTITY1));
         verifyCandidates(leaderDistributedDataStore, ENTITY1, "member-1", "member-2");
         verifyOwner(leaderDistributedDataStore, ENTITY1, "member-1");
         verify(leaderMockListener, timeout(300).never()).ownershipChanged(ownershipChange(ENTITY1));
@@ -187,21 +178,21 @@ public class DistributedEntityOwnershipIntegrationTest {
 
         // Register follower1 candidate for entity2 and verify it becomes owner
 
 
         // Register follower1 candidate for entity2 and verify it becomes owner
 
-        follower1EntityOwnershipService.registerCandidate(ENTITY2, follower1MockCandidate);
-        verify(follower1MockCandidate, timeout(5000)).ownershipChanged(ownershipChange(ENTITY2, false, true, true));
+        follower1EntityOwnershipService.registerCandidate(ENTITY2);
+        verify(follower1MockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY2, false, true, true));
         verify(leaderMockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY2, false, false, true));
         reset(leaderMockListener, follower1MockListener);
 
         // Register follower2 candidate for entity2 and verify it gets added but doesn't become owner
 
         follower2EntityOwnershipService.registerListener(ENTITY_TYPE1, follower2MockListener);
         verify(leaderMockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY2, false, false, true));
         reset(leaderMockListener, follower1MockListener);
 
         // Register follower2 candidate for entity2 and verify it gets added but doesn't become owner
 
         follower2EntityOwnershipService.registerListener(ENTITY_TYPE1, follower2MockListener);
-        follower2EntityOwnershipService.registerCandidate(ENTITY2, follower2MockCandidate);
+        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
 
         verifyCandidates(leaderDistributedDataStore, ENTITY2, "member-2", "member-3");
         verifyOwner(leaderDistributedDataStore, ENTITY2, "member-2");
 
         // Unregister follower1 candidate for entity2 and verify follower2 becomes owner
 
-        follower1EntityOwnershipService.unregisterCandidate(ENTITY2, follower1MockCandidate);
+        follower1EntityOwnershipService.unregisterCandidate(ENTITY2);
         verifyOwner(leaderDistributedDataStore, ENTITY2, "member-3");
         verify(follower2MockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY2, false, true, true));
         verify(follower1MockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY2, true, false, true));
         verifyOwner(leaderDistributedDataStore, ENTITY2, "member-3");
         verify(follower2MockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY2, false, true, true));
         verify(follower1MockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY2, true, false, true));
@@ -210,7 +201,7 @@ public class DistributedEntityOwnershipIntegrationTest {
 
         // Register follower1 candidate for entity3 and verify it becomes owner
 
 
         // Register follower1 candidate for entity3 and verify it becomes owner
 
-        follower1EntityOwnershipService.registerCandidate(ENTITY3, follower1MockCandidate);
+        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));
         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));
@@ -218,17 +209,16 @@ public class DistributedEntityOwnershipIntegrationTest {
 
         // Register follower2 candidate for entity4 and verify it becomes owner
 
 
         // Register follower2 candidate for entity4 and verify it becomes owner
 
-        follower2EntityOwnershipService.registerCandidate(ENTITY4, follower2MockCandidate);
+        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));
         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(follower2MockListener);
+        reset(follower1MockListener, follower2MockListener);
 
         // Register follower1 candidate for entity4 and verify it gets added but doesn't become owner
 
 
         // Register follower1 candidate for entity4 and verify it gets added but doesn't become owner
 
-        reset(follower1MockCandidate);
-        follower1EntityOwnershipService.registerCandidate(ENTITY4, follower1MockCandidate);
+        follower1EntityOwnershipService.registerCandidate(ENTITY4);
         verifyCandidates(leaderDistributedDataStore, ENTITY4, "member-3", "member-2");
         verifyOwner(leaderDistributedDataStore, ENTITY4, "member-3");
 
         verifyCandidates(leaderDistributedDataStore, ENTITY4, "member-3", "member-2");
         verifyOwner(leaderDistributedDataStore, ENTITY4, "member-3");
 
@@ -244,13 +234,13 @@ public class DistributedEntityOwnershipIntegrationTest {
 
         // Register leader candidate for entity2 and verify it becomes owner
 
 
         // Register leader candidate for entity2 and verify it becomes owner
 
-        leaderEntityOwnershipService.registerCandidate(ENTITY2, leaderMockCandidate);
+        leaderEntityOwnershipService.registerCandidate(ENTITY2);
         verify(leaderMockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY2, false, true, true));
         verifyOwner(leaderDistributedDataStore, ENTITY2, "member-1");
 
         // Unregister leader candidate for entity2 and verify the owner is cleared
 
         verify(leaderMockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY2, false, true, true));
         verifyOwner(leaderDistributedDataStore, ENTITY2, "member-1");
 
         // Unregister leader candidate for entity2 and verify the owner is cleared
 
-        leaderEntityOwnershipService.unregisterCandidate(ENTITY2, leaderMockCandidate);
+        leaderEntityOwnershipService.unregisterCandidate(ENTITY2);
         verifyOwner(leaderDistributedDataStore, ENTITY2, "");
         verify(leaderMockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY2, true, false, false));
         verify(follower1MockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY2, false, false, false));
         verifyOwner(leaderDistributedDataStore, ENTITY2, "");
         verify(leaderMockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY2, true, false, false));
         verify(follower1MockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY2, false, false, false));
index 51f042ddacc10521cebb544b4d8eaa585b0d1596..c1c16a98b9b8bac2a965c1038ce0a59f8199b15f 100644 (file)
@@ -41,7 +41,6 @@ import org.opendaylight.controller.cluster.datastore.utils.MockClusterWrapper;
 import org.opendaylight.controller.md.cluster.datastore.model.SchemaContextHelper;
 import org.opendaylight.controller.md.sal.common.api.clustering.CandidateAlreadyRegisteredException;
 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
 import org.opendaylight.controller.md.cluster.datastore.model.SchemaContextHelper;
 import org.opendaylight.controller.md.sal.common.api.clustering.CandidateAlreadyRegisteredException;
 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidate;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidateRegistration;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidateRegistration;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration;
@@ -118,24 +117,21 @@ public class DistributedEntityOwnershipServiceTest extends AbstractEntityOwnersh
 
         YangInstanceIdentifier entityId = YangInstanceIdentifier.of(QNAME);
         Entity entity = new Entity(ENTITY_TYPE, entityId);
 
         YangInstanceIdentifier entityId = YangInstanceIdentifier.of(QNAME);
         Entity entity = new Entity(ENTITY_TYPE, entityId);
-        EntityOwnershipCandidate candidate = mock(EntityOwnershipCandidate.class);
 
 
-        EntityOwnershipCandidateRegistration reg = service.registerCandidate(entity, candidate);
+        EntityOwnershipCandidateRegistration reg = service.registerCandidate(entity);
 
         verifyEntityOwnershipCandidateRegistration(entity, reg);
 
         verifyEntityOwnershipCandidateRegistration(entity, reg);
-        verifyRegisterCandidateLocal(shardPropsCreator, entity, candidate);
+        verifyRegisterCandidateLocal(shardPropsCreator, entity);
         verifyEntityCandidate(service.getLocalEntityOwnershipShard(), ENTITY_TYPE, entityId,
                 dataStore.getActorContext().getCurrentMemberName());
 
         // Register the same entity - should throw exception
 
         verifyEntityCandidate(service.getLocalEntityOwnershipShard(), ENTITY_TYPE, entityId,
                 dataStore.getActorContext().getCurrentMemberName());
 
         // Register the same entity - should throw exception
 
-        EntityOwnershipCandidate candidate2 = mock(EntityOwnershipCandidate.class);
         try {
         try {
-            service.registerCandidate(entity, candidate2);
+            service.registerCandidate(entity);
             fail("Expected CandidateAlreadyRegisteredException");
         } catch(CandidateAlreadyRegisteredException e) {
             // expected
             fail("Expected CandidateAlreadyRegisteredException");
         } catch(CandidateAlreadyRegisteredException e) {
             // expected
-            assertSame("getCandidate", candidate, e.getRegisteredCandidate());
             assertEquals("getEntity", entity, e.getEntity());
         }
 
             assertEquals("getEntity", entity, e.getEntity());
         }
 
@@ -144,10 +140,10 @@ public class DistributedEntityOwnershipServiceTest extends AbstractEntityOwnersh
         Entity entity2 = new Entity(ENTITY_TYPE2, entityId);
         shardPropsCreator.expectShardMessage(RegisterCandidateLocal.class);
 
         Entity entity2 = new Entity(ENTITY_TYPE2, entityId);
         shardPropsCreator.expectShardMessage(RegisterCandidateLocal.class);
 
-        EntityOwnershipCandidateRegistration reg2 = service.registerCandidate(entity2, candidate);
+        EntityOwnershipCandidateRegistration reg2 = service.registerCandidate(entity2);
 
         verifyEntityOwnershipCandidateRegistration(entity2, reg2);
 
         verifyEntityOwnershipCandidateRegistration(entity2, reg2);
-        verifyRegisterCandidateLocal(shardPropsCreator, entity2, candidate);
+        verifyRegisterCandidateLocal(shardPropsCreator, entity2);
         verifyEntityCandidate(service.getLocalEntityOwnershipShard(), ENTITY_TYPE2, entityId,
                 dataStore.getActorContext().getCurrentMemberName());
 
         verifyEntityCandidate(service.getLocalEntityOwnershipShard(), ENTITY_TYPE2, entityId,
                 dataStore.getActorContext().getCurrentMemberName());
 
@@ -169,12 +165,11 @@ public class DistributedEntityOwnershipServiceTest extends AbstractEntityOwnersh
         shardPropsCreator.expectShardMessage(RegisterCandidateLocal.class);
 
         Entity entity = new Entity(ENTITY_TYPE, YangInstanceIdentifier.of(QNAME));
         shardPropsCreator.expectShardMessage(RegisterCandidateLocal.class);
 
         Entity entity = new Entity(ENTITY_TYPE, YangInstanceIdentifier.of(QNAME));
-        EntityOwnershipCandidate candidate = mock(EntityOwnershipCandidate.class);
 
 
-        EntityOwnershipCandidateRegistration reg = service.registerCandidate(entity, candidate);
+        EntityOwnershipCandidateRegistration reg = service.registerCandidate(entity);
 
         verifyEntityOwnershipCandidateRegistration(entity, reg);
 
         verifyEntityOwnershipCandidateRegistration(entity, reg);
-        verifyRegisterCandidateLocal(shardPropsCreator, entity, candidate);
+        verifyRegisterCandidateLocal(shardPropsCreator, entity);
 
         shardPropsCreator.expectShardMessage(UnregisterCandidateLocal.class);
 
 
         shardPropsCreator.expectShardMessage(UnregisterCandidateLocal.class);
 
@@ -182,15 +177,14 @@ public class DistributedEntityOwnershipServiceTest extends AbstractEntityOwnersh
 
         UnregisterCandidateLocal unregCandidate = shardPropsCreator.waitForShardMessage();
         assertEquals("getEntity", entity, unregCandidate.getEntity());
 
         UnregisterCandidateLocal unregCandidate = shardPropsCreator.waitForShardMessage();
         assertEquals("getEntity", entity, unregCandidate.getEntity());
-        assertSame("getCandidate", candidate, unregCandidate.getCandidate());
 
         // Re-register - should succeed.
 
         shardPropsCreator.expectShardMessage(RegisterCandidateLocal.class);
 
 
         // Re-register - should succeed.
 
         shardPropsCreator.expectShardMessage(RegisterCandidateLocal.class);
 
-        service.registerCandidate(entity, candidate);
+        service.registerCandidate(entity);
 
 
-        verifyRegisterCandidateLocal(shardPropsCreator, entity, candidate);
+        verifyRegisterCandidateLocal(shardPropsCreator, entity);
 
         service.close();
     }
 
         service.close();
     }
@@ -249,16 +243,14 @@ public class DistributedEntityOwnershipServiceTest extends AbstractEntityOwnersh
                 });
     }
 
                 });
     }
 
-    private void verifyRegisterCandidateLocal(final TestShardPropsCreator shardPropsCreator, Entity entity,
-            EntityOwnershipCandidate candidate) {
+    private void verifyRegisterCandidateLocal(final TestShardPropsCreator shardPropsCreator, Entity entity) {
         RegisterCandidateLocal regCandidate = shardPropsCreator.waitForShardMessage();
         RegisterCandidateLocal regCandidate = shardPropsCreator.waitForShardMessage();
-        assertSame("getCandidate", candidate, regCandidate.getCandidate());
         assertEquals("getEntity", entity, regCandidate.getEntity());
     }
 
     private void verifyEntityOwnershipCandidateRegistration(Entity entity, EntityOwnershipCandidateRegistration reg) {
         assertNotNull("EntityOwnershipCandidateRegistration null", reg);
         assertEquals("getEntity", entity, regCandidate.getEntity());
     }
 
     private void verifyEntityOwnershipCandidateRegistration(Entity entity, EntityOwnershipCandidateRegistration reg) {
         assertNotNull("EntityOwnershipCandidateRegistration null", reg);
-        assertEquals("getEntity", entity, reg.getEntity());
+        assertEquals("getInstance", entity, reg.getInstance());
     }
 
     static class TestShardPropsCreator extends EntityOwnershipShardPropsCreator {
     }
 
     static class TestShardPropsCreator extends EntityOwnershipShardPropsCreator {
index 2394ee0bb15b5a6e35e92f2607198ad7cda827b4..9e41757be19d8c1e24ca8fe0e7e3a897d169ed8c 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.controller.cluster.datastore.entityownership;
 
 import static org.junit.Assert.assertEquals;
 package org.opendaylight.controller.cluster.datastore.entityownership;
 
 import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
@@ -18,17 +19,15 @@ import akka.actor.ActorRef;
 import akka.actor.Props;
 import akka.testkit.JavaTestKit;
 import akka.testkit.TestActorRef;
 import akka.actor.Props;
 import akka.testkit.JavaTestKit;
 import akka.testkit.TestActorRef;
-import com.google.common.util.concurrent.Uninterruptibles;
 import java.util.ArrayList;
 import java.util.List;
 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.controller.md.sal.common.api.clustering.Entity;
 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.controller.md.sal.common.api.clustering.Entity;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidate;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipChange;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
@@ -63,95 +62,62 @@ public class EntityOwnershipListenerSupportTest extends AbstractEntityOwnershipT
 
         EntityOwnershipListener mockListener1 = mock(EntityOwnershipListener.class, "EntityOwnershipListener1");
         EntityOwnershipListener mockListener2 = mock(EntityOwnershipListener.class, "EntityOwnershipListener2");
 
         EntityOwnershipListener mockListener1 = mock(EntityOwnershipListener.class, "EntityOwnershipListener1");
         EntityOwnershipListener mockListener2 = mock(EntityOwnershipListener.class, "EntityOwnershipListener2");
-        EntityOwnershipListener mockListener3 = mock(EntityOwnershipListener.class, "EntityOwnershipListener3");
-        Entity entity1 = new Entity("type1", YangInstanceIdentifier.of(QName.create("test", "id1")));
-        Entity entity2 = new Entity("type1", YangInstanceIdentifier.of(QName.create("test", "id2")));
-        Entity entity3 = new Entity("type1", YangInstanceIdentifier.of(QName.create("test", "id3")));
-        Entity entity4 = new Entity("type2", YangInstanceIdentifier.of(QName.create("test", "id4")));
-        Entity entity5 = new Entity("noListener", YangInstanceIdentifier.of(QName.create("test", "id5")));
+        EntityOwnershipListener mockListener1_2 = mock(EntityOwnershipListener.class, "EntityOwnershipListener1_2");
+        String entityType1 = "type1";
+        String entityType2 = "type2";
+        Entity entity1 = new Entity(entityType1, YangInstanceIdentifier.of(QName.create("test", "id1")));
+        Entity entity2 = new Entity(entityType2, YangInstanceIdentifier.of(QName.create("test", "id2")));
+        Entity entity3 = new Entity("noListener", YangInstanceIdentifier.of(QName.create("test", "id5")));
 
         // Add EntityOwnershipListener registrations.
 
 
         // Add EntityOwnershipListener registrations.
 
-        support.addEntityOwnershipListener(entity1, mockListener1);
-        support.addEntityOwnershipListener(entity1, mockListener1); // register again - should be noop
-        support.addEntityOwnershipListener(entity2, mockListener1);
-        support.addEntityOwnershipListener(entity1, mockListener2);
-        support.addEntityOwnershipListener(entity1.getType(), mockListener3);
+        support.addEntityOwnershipListener(entityType1, mockListener1);
+        support.addEntityOwnershipListener(entityType1, mockListener1); // register again - should be noop
+        support.addEntityOwnershipListener(entityType1, mockListener1_2);
+        support.addEntityOwnershipListener(entityType2, mockListener2);
 
 
-        // Notify entity1 changed and verify listeners are notified.
+        // 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));
 
         support.notifyEntityOwnershipListeners(entity1, false, true, true);
 
         verify(mockListener1, timeout(5000)).ownershipChanged(ownershipChange(entity1, false, true, true));
-        verify(mockListener2, timeout(5000)).ownershipChanged(ownershipChange(entity1, false, true, true));
-        verify(mockListener3, timeout(5000)).ownershipChanged(ownershipChange(entity1, false, true, true));
-        assertEquals("# of listener actors", 3, actorContext.children().size());
+        verify(mockListener1_2, timeout(5000)).ownershipChanged(ownershipChange(entity1, false, true, true));
+        verify(mockListener2, timeout(300).never()).ownershipChanged(any(EntityOwnershipChange.class));
+        assertEquals("# of listener actors", 2, actorContext.children().size());
+        reset(mockListener1, mockListener2, mockListener1_2);
 
 
-        // Notify entity2 changed and verify only mockListener1 and mockListener3 are notified.
+        // Notify entity2 changed and verify appropriate listeners are notified.
 
 
-        support.notifyEntityOwnershipListeners(entity2, false, false, false);
+        support.notifyEntityOwnershipListeners(entity2, false, true, true);
 
 
-        verify(mockListener1, timeout(5000)).ownershipChanged(ownershipChange(entity2, false, false, false));
-        verify(mockListener3, timeout(5000)).ownershipChanged(ownershipChange(entity2, false, false, false));
-        Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
-        verify(mockListener2, never()).ownershipChanged(ownershipChange(entity2));
+        verify(mockListener2, timeout(5000)).ownershipChanged(ownershipChange(entity2, false, true, true));
+        verify(mockListener1, timeout(300).never()).ownershipChanged(any(EntityOwnershipChange.class));
+        verify(mockListener1_2, never()).ownershipChanged(any(EntityOwnershipChange.class));
         assertEquals("# of listener actors", 3, actorContext.children().size());
         assertEquals("# of listener actors", 3, actorContext.children().size());
+        reset(mockListener1, mockListener2, mockListener1_2);
 
 
-        // Notify entity3 changed and verify only mockListener3 is notified.
-
-        support.notifyEntityOwnershipListeners(entity3, false, true, true);
-
-        verify(mockListener3, timeout(5000)).ownershipChanged(ownershipChange(entity3, false, true, true));
-        Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
-        verify(mockListener1, never()).ownershipChanged(ownershipChange(entity3));
-        verify(mockListener2, never()).ownershipChanged(ownershipChange(entity3));
-
-        // Notify entity4 changed and verify no listeners are notified.
-
-        support.notifyEntityOwnershipListeners(entity4, true, false, true);
-
-        Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
-        verify(mockListener1, never()).ownershipChanged(ownershipChange(entity4));
-        verify(mockListener2, never()).ownershipChanged(ownershipChange(entity4));
-        verify(mockListener3, never()).ownershipChanged(ownershipChange(entity4));
+        // Notify entity3 changed and verify no listeners are notified.
 
 
-        // Notify entity5 changed and verify no listener is notified.
+        support.notifyEntityOwnershipListeners(entity3, true, false, true);
 
 
-        support.notifyEntityOwnershipListeners(entity5, true, false, true);
+        verify(mockListener1, timeout(300).never()).ownershipChanged(any(EntityOwnershipChange.class));
+        verify(mockListener2, never()).ownershipChanged(any(EntityOwnershipChange.class));
+        verify(mockListener1_2, never()).ownershipChanged(any(EntityOwnershipChange.class));
+        reset(mockListener1, mockListener2, mockListener1_2);
 
 
-        Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
-        verify(mockListener1, never()).ownershipChanged(ownershipChange(entity4));
-        verify(mockListener2, never()).ownershipChanged(ownershipChange(entity4));
-        verify(mockListener3, never()).ownershipChanged(ownershipChange(entity4));
-
-        reset(mockListener1, mockListener2, mockListener3);
+        Iterable<ActorRef> listenerActors = actorContext.children();
+        assertEquals("# of listener actors", 3, listenerActors.size());
 
 
-        // Unregister mockListener1 for entity1, issue a change and verify only mockListeners 2 & 3 are notified.
+        // Unregister mockListener1, issue a change for entity1 and verify only remaining listeners are notified.
 
 
-        support.removeEntityOwnershipListener(entity1, mockListener1);
+        support.removeEntityOwnershipListener(entityType1, mockListener1);
         support.notifyEntityOwnershipListeners(entity1, true, false, true);
 
         support.notifyEntityOwnershipListeners(entity1, true, false, true);
 
-        verify(mockListener2, timeout(5000)).ownershipChanged(ownershipChange(entity1, true, false, true));
-        verify(mockListener3, timeout(5000)).ownershipChanged(ownershipChange(entity1, true, false, true));
-        Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
-        verify(mockListener1, never()).ownershipChanged(ownershipChange(entity1));
-
-        // Unregister mockListener3, issue a change for entity1 and verify only mockListeners2 is notified.
-
-        reset(mockListener1, mockListener2, mockListener3);
-
-        support.removeEntityOwnershipListener(entity1.getType(), mockListener3);
-        support.notifyEntityOwnershipListeners(entity1, false, false, false);
+        verify(mockListener1_2, timeout(5000)).ownershipChanged(ownershipChange(entity1, true, false, true));
+        verify(mockListener1, timeout(300).never()).ownershipChanged(any(EntityOwnershipChange.class));
+        reset(mockListener1, mockListener2, mockListener1_2);
 
 
-        verify(mockListener2, timeout(5000)).ownershipChanged(ownershipChange(entity1, false, false, false));
-        Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
-        verify(mockListener1, never()).ownershipChanged(ownershipChange(entity1));
-        verify(mockListener3, never()).ownershipChanged(ownershipChange(entity1));
-
-        // Completely unregister all listeners and verify their listener actors are destroyed.
-
-        Iterable<ActorRef> listenerActors = actorContext.children();
-        assertEquals("# of listener actors", 2, listenerActors.size());
+        // Unregister all listeners and verify their listener actors are destroyed.
 
         List<JavaTestKit> watchers = new ArrayList<>();
         for(Iterator<ActorRef> iter = listenerActors.iterator(); iter.hasNext();) {
 
         List<JavaTestKit> watchers = new ArrayList<>();
         for(Iterator<ActorRef> iter = listenerActors.iterator(); iter.hasNext();) {
@@ -160,9 +126,9 @@ public class EntityOwnershipListenerSupportTest extends AbstractEntityOwnershipT
             watchers.add(kit);
         }
 
             watchers.add(kit);
         }
 
-        support.removeEntityOwnershipListener(entity2, mockListener1);
-        support.removeEntityOwnershipListener(entity2, mockListener1); // un-register again - shoild be noop
-        support.removeEntityOwnershipListener(entity1, mockListener2);
+        support.removeEntityOwnershipListener(entityType1, mockListener1_2);
+        support.removeEntityOwnershipListener(entityType1, mockListener1_2); // un-register again - should be noop
+        support.removeEntityOwnershipListener(entityType2, mockListener2);
 
         Iterator<ActorRef> iter = listenerActors.iterator();
         for(JavaTestKit kit: watchers) {
 
         Iterator<ActorRef> iter = listenerActors.iterator();
         for(JavaTestKit kit: watchers) {
@@ -171,22 +137,21 @@ public class EntityOwnershipListenerSupportTest extends AbstractEntityOwnershipT
 
         assertEquals("# of listener actors", 0, actorContext.children().size());
 
 
         assertEquals("# of listener actors", 0, actorContext.children().size());
 
-        // Re-register mockListener1 for entity1 and verify it is notified.
+        // Re-register mockListener1 and verify it is notified.
 
         reset(mockListener1, mockListener2);
 
 
         reset(mockListener1, mockListener2);
 
-        support.addEntityOwnershipListener(entity1, mockListener1);
-
+        support.addEntityOwnershipListener(entityType1, mockListener1);
         support.notifyEntityOwnershipListeners(entity1, false, false, true);
 
         verify(mockListener1, timeout(5000)).ownershipChanged(ownershipChange(entity1, false, false, true));
         support.notifyEntityOwnershipListeners(entity1, false, false, true);
 
         verify(mockListener1, timeout(5000)).ownershipChanged(ownershipChange(entity1, false, false, true));
-        verify(mockListener2, never()).ownershipChanged(ownershipChange(entity1));
-        verify(mockListener3, never()).ownershipChanged(ownershipChange(entity1));
+        verify(mockListener1_2, never()).ownershipChanged(any(EntityOwnershipChange.class));
+        verify(mockListener2, never()).ownershipChanged(any(EntityOwnershipChange.class));
 
         // Quickly register and unregister mockListener2 - expecting no exceptions.
 
 
         // Quickly register and unregister mockListener2 - expecting no exceptions.
 
-        support.addEntityOwnershipListener(entity1, mockListener2);
-        support.removeEntityOwnershipListener(entity1, mockListener2);
+        support.addEntityOwnershipListener(entityType1, mockListener2);
+        support.removeEntityOwnershipListener(entityType1, mockListener2);
     }
 
     @Test
     }
 
     @Test
@@ -196,14 +161,17 @@ public class EntityOwnershipListenerSupportTest extends AbstractEntityOwnershipT
 
         assertEquals("hasCandidateForEntity", false, support.hasCandidateForEntity(entity));
 
 
         assertEquals("hasCandidateForEntity", false, support.hasCandidateForEntity(entity));
 
-        support.addEntityOwnershipListener(entity, mock(EntityOwnershipListener.class));
-        assertEquals("hasCandidateForEntity", false, support.hasCandidateForEntity(entity));
-
-        EntityOwnershipCandidate candidate = mock(EntityOwnershipCandidate.class);
-        support.addEntityOwnershipListener(entity, candidate);
+        support.setHasCandidateForEntity(entity);
+        support.setHasCandidateForEntity(entity); // set again - should be noop
         assertEquals("hasCandidateForEntity", true, support.hasCandidateForEntity(entity));
 
         assertEquals("hasCandidateForEntity", true, support.hasCandidateForEntity(entity));
 
-        support.removeEntityOwnershipListener(entity, candidate);
+        support.unsetHasCandidateForEntity(entity);
+        assertEquals("hasCandidateForEntity", false, support.hasCandidateForEntity(entity));
+
+        support.unsetHasCandidateForEntity(entity); // unset again - should be noop
         assertEquals("hasCandidateForEntity", false, support.hasCandidateForEntity(entity));
         assertEquals("hasCandidateForEntity", false, support.hasCandidateForEntity(entity));
+
+        support.setHasCandidateForEntity(entity);
+        assertEquals("hasCandidateForEntity", true, support.hasCandidateForEntity(entity));
     }
 }
     }
 }
index c2fbfea98fa3cbf4c70068a89df78b8b1c2028aa..e78be76e23cdf27f3c304a33d3fce6a51ed3e364 100644 (file)
@@ -66,7 +66,6 @@ import org.opendaylight.controller.cluster.raft.messages.RequestVote;
 import org.opendaylight.controller.cluster.raft.messages.RequestVoteReply;
 import org.opendaylight.controller.md.cluster.datastore.model.SchemaContextHelper;
 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
 import org.opendaylight.controller.cluster.raft.messages.RequestVoteReply;
 import org.opendaylight.controller.md.cluster.datastore.model.SchemaContextHelper;
 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidate;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipChange;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipChange;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -113,14 +112,12 @@ public class EntityOwnershipShardTest extends AbstractEntityOwnershipTest {
 
         YangInstanceIdentifier entityId = ENTITY_ID1;
         Entity entity = new Entity(ENTITY_TYPE, entityId);
 
         YangInstanceIdentifier entityId = ENTITY_ID1;
         Entity entity = new Entity(ENTITY_TYPE, entityId);
-        EntityOwnershipCandidate candidate = mock(EntityOwnershipCandidate.class);
 
 
-        shard.tell(new RegisterCandidateLocal(candidate, entity), kit.getRef());
+        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);
         kit.expectMsgClass(SuccessReply.class);
 
         verifyCommittedEntityCandidate(shard, ENTITY_TYPE, entityId, LOCAL_MEMBER_NAME);
         verifyOwner(shard, ENTITY_TYPE, entityId, LOCAL_MEMBER_NAME);
-        verify(candidate, timeout(5000)).ownershipChanged(ownershipChange(entity, false, true, true));
     }
 
     @Test
     }
 
     @Test
@@ -139,19 +136,15 @@ public class EntityOwnershipShardTest extends AbstractEntityOwnershipTest {
 
         YangInstanceIdentifier entityId = ENTITY_ID1;
         Entity entity = new Entity(ENTITY_TYPE, entityId);
 
         YangInstanceIdentifier entityId = ENTITY_ID1;
         Entity entity = new Entity(ENTITY_TYPE, entityId);
-        EntityOwnershipCandidate candidate = mock(EntityOwnershipCandidate.class);
 
 
-        shard.tell(new RegisterCandidateLocal(candidate, entity), kit.getRef());
+        shard.tell(new RegisterCandidateLocal(entity), kit.getRef());
         kit.expectMsgClass(SuccessReply.class);
 
         // Now grant the vote so the shard becomes the leader. This should retry the commit.
         peer.underlyingActor().grantVote = true;
 
         verifyCommittedEntityCandidate(shard, ENTITY_TYPE, entityId, LOCAL_MEMBER_NAME);
         kit.expectMsgClass(SuccessReply.class);
 
         // Now grant the vote so the shard becomes the leader. This should retry the commit.
         peer.underlyingActor().grantVote = true;
 
         verifyCommittedEntityCandidate(shard, ENTITY_TYPE, entityId, LOCAL_MEMBER_NAME);
-
         verifyOwner(shard, ENTITY_TYPE, entityId, LOCAL_MEMBER_NAME);
         verifyOwner(shard, ENTITY_TYPE, entityId, LOCAL_MEMBER_NAME);
-
-        verify(candidate, timeout(5000)).ownershipChanged(ownershipChange(entity, false, true, true));
     }
 
     @Test
     }
 
     @Test
@@ -178,9 +171,8 @@ public class EntityOwnershipShardTest extends AbstractEntityOwnershipTest {
 
         YangInstanceIdentifier entityId = ENTITY_ID1;
         Entity entity = new Entity(ENTITY_TYPE, entityId);
 
         YangInstanceIdentifier entityId = ENTITY_ID1;
         Entity entity = new Entity(ENTITY_TYPE, entityId);
-        EntityOwnershipCandidate candidate = mock(EntityOwnershipCandidate.class);
 
 
-        shard.tell(new RegisterCandidateLocal(candidate, entity), kit.getRef());
+        shard.tell(new RegisterCandidateLocal(entity), kit.getRef());
         kit.expectMsgClass(SuccessReply.class);
 
         // Wait enough time for the commit to timeout.
         kit.expectMsgClass(SuccessReply.class);
 
         // Wait enough time for the commit to timeout.
@@ -191,10 +183,7 @@ public class EntityOwnershipShardTest extends AbstractEntityOwnershipTest {
         follower.dropAppendEntries = false;
 
         verifyCommittedEntityCandidate(shard, ENTITY_TYPE, entityId, LOCAL_MEMBER_NAME);
         follower.dropAppendEntries = false;
 
         verifyCommittedEntityCandidate(shard, ENTITY_TYPE, entityId, LOCAL_MEMBER_NAME);
-
         verifyOwner(shard, ENTITY_TYPE, entityId, LOCAL_MEMBER_NAME);
         verifyOwner(shard, ENTITY_TYPE, entityId, LOCAL_MEMBER_NAME);
-
-        verify(candidate, timeout(5000)).ownershipChanged(ownershipChange(entity, false, true, true));
     }
 
     @Test
     }
 
     @Test
@@ -222,18 +211,14 @@ public class EntityOwnershipShardTest extends AbstractEntityOwnershipTest {
 
         YangInstanceIdentifier entityId = ENTITY_ID1;
         Entity entity = new Entity(ENTITY_TYPE, entityId);
 
         YangInstanceIdentifier entityId = ENTITY_ID1;
         Entity entity = new Entity(ENTITY_TYPE, entityId);
-        EntityOwnershipCandidate candidate = mock(EntityOwnershipCandidate.class);
 
 
-        shard.tell(new RegisterCandidateLocal(candidate, entity), kit.getRef());
+        shard.tell(new RegisterCandidateLocal(entity), kit.getRef());
         kit.expectMsgClass(SuccessReply.class);
 
         // Resume AppendEntries - the candidate write should now be committed.
         follower.dropAppendEntries = false;
         verifyCommittedEntityCandidate(shard, ENTITY_TYPE, entityId, LOCAL_MEMBER_NAME);
         kit.expectMsgClass(SuccessReply.class);
 
         // Resume AppendEntries - the candidate write should now be committed.
         follower.dropAppendEntries = false;
         verifyCommittedEntityCandidate(shard, ENTITY_TYPE, entityId, LOCAL_MEMBER_NAME);
-
         verifyOwner(shard, ENTITY_TYPE, entityId, LOCAL_MEMBER_NAME);
         verifyOwner(shard, ENTITY_TYPE, entityId, LOCAL_MEMBER_NAME);
-
-        verify(candidate, timeout(5000)).ownershipChanged(ownershipChange(entity, false, true, true));
     }
 
     @Test
     }
 
     @Test
@@ -255,9 +240,7 @@ public class EntityOwnershipShardTest extends AbstractEntityOwnershipTest {
         shard.tell(new AppendEntries(1L, peerId, -1L, -1L, Collections.<ReplicatedLogEntry>emptyList(), -1L, -1L,
                 DataStoreVersions.CURRENT_VERSION), peer);
 
         shard.tell(new AppendEntries(1L, peerId, -1L, -1L, Collections.<ReplicatedLogEntry>emptyList(), -1L, -1L,
                 DataStoreVersions.CURRENT_VERSION), peer);
 
-        EntityOwnershipCandidate candidate = mock(EntityOwnershipCandidate.class);
-
-        shard.tell(new RegisterCandidateLocal(candidate, new Entity(ENTITY_TYPE, ENTITY_ID1)), kit.getRef());
+        shard.tell(new RegisterCandidateLocal(new Entity(ENTITY_TYPE, ENTITY_ID1)), kit.getRef());
         kit.expectMsgClass(SuccessReply.class);
 
         MockLeader leader = peer.underlyingActor();
         kit.expectMsgClass(SuccessReply.class);
 
         MockLeader leader = peer.underlyingActor();
@@ -273,7 +256,7 @@ public class EntityOwnershipShardTest extends AbstractEntityOwnershipTest {
 
         shard.tell(dataStoreContextBuilder.shardTransactionCommitTimeoutInSeconds(1).build(), ActorRef.noSender());
 
 
         shard.tell(dataStoreContextBuilder.shardTransactionCommitTimeoutInSeconds(1).build(), ActorRef.noSender());
 
-        shard.tell(new RegisterCandidateLocal(candidate, new Entity(ENTITY_TYPE, ENTITY_ID2)), kit.getRef());
+        shard.tell(new RegisterCandidateLocal(new Entity(ENTITY_TYPE, ENTITY_ID2)), kit.getRef());
         kit.expectMsgClass(SuccessReply.class);
 
         assertEquals("Leader received BatchedModifications", true, Uninterruptibles.awaitUninterruptibly(
         kit.expectMsgClass(SuccessReply.class);
 
         assertEquals("Leader received BatchedModifications", true, Uninterruptibles.awaitUninterruptibly(
@@ -290,7 +273,7 @@ public class EntityOwnershipShardTest extends AbstractEntityOwnershipTest {
         for(int i = 1; i <= max; i++) {
             YangInstanceIdentifier id = YangInstanceIdentifier.of(QName.create("test", "2015-08-14", "test" + i));
             entityIds.add(id);
         for(int i = 1; i <= max; i++) {
             YangInstanceIdentifier id = YangInstanceIdentifier.of(QName.create("test", "2015-08-14", "test" + i));
             entityIds.add(id);
-            shard.tell(new RegisterCandidateLocal(candidate, new Entity(ENTITY_TYPE, id)), kit.getRef());
+            shard.tell(new RegisterCandidateLocal(new Entity(ENTITY_TYPE, id)), kit.getRef());
         }
 
         assertEquals("Leader received BatchedModifications", true, Uninterruptibles.awaitUninterruptibly(
         }
 
         assertEquals("Leader received BatchedModifications", true, Uninterruptibles.awaitUninterruptibly(
@@ -315,35 +298,29 @@ public class EntityOwnershipShardTest extends AbstractEntityOwnershipTest {
         kit.waitUntilLeader(shard);
 
         Entity entity = new Entity(ENTITY_TYPE, ENTITY_ID1);
         kit.waitUntilLeader(shard);
 
         Entity entity = new Entity(ENTITY_TYPE, ENTITY_ID1);
-        EntityOwnershipCandidate candidate = mock(EntityOwnershipCandidate.class);
 
         // Register
 
 
         // Register
 
-        shard.tell(new RegisterCandidateLocal(candidate, entity), kit.getRef());
+        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);
         kit.expectMsgClass(SuccessReply.class);
 
         verifyCommittedEntityCandidate(shard, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
         verifyOwner(shard, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
-        verify(candidate, timeout(5000)).ownershipChanged(ownershipChange(entity, false, true, true));
 
         // Unregister
 
 
         // Unregister
 
-        reset(candidate);
-
-        shard.tell(new UnregisterCandidateLocal(candidate, entity), kit.getRef());
+        shard.tell(new UnregisterCandidateLocal(entity), kit.getRef());
         kit.expectMsgClass(SuccessReply.class);
 
         verifyOwner(shard, ENTITY_TYPE, ENTITY_ID1, "");
         kit.expectMsgClass(SuccessReply.class);
 
         verifyOwner(shard, ENTITY_TYPE, ENTITY_ID1, "");
-        //verify(candidate).ownershipChanged(entity, true, false, false);
 
         // Register again
 
 
         // Register again
 
-        shard.tell(new RegisterCandidateLocal(candidate, entity), kit.getRef());
+        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);
         kit.expectMsgClass(SuccessReply.class);
 
         verifyCommittedEntityCandidate(shard, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
         verifyOwner(shard, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
-        verify(candidate, timeout(5000)).ownershipChanged(ownershipChange(entity, false, true, true));
     }
 
     @Test
     }
 
     @Test
@@ -353,7 +330,6 @@ public class EntityOwnershipShardTest extends AbstractEntityOwnershipTest {
         kit.waitUntilLeader(shard);
 
         Entity entity = new Entity(ENTITY_TYPE, ENTITY_ID1);
         kit.waitUntilLeader(shard);
 
         Entity entity = new Entity(ENTITY_TYPE, ENTITY_ID1);
-        EntityOwnershipCandidate candidate = mock(EntityOwnershipCandidate.class);
         ShardDataTree shardDataTree = shard.underlyingActor().getDataStore();
 
         // Add a remote candidate
         ShardDataTree shardDataTree = shard.underlyingActor().getDataStore();
 
         // Add a remote candidate
@@ -363,7 +339,7 @@ public class EntityOwnershipShardTest extends AbstractEntityOwnershipTest {
 
         // Register local
 
 
         // Register local
 
-        shard.tell(new RegisterCandidateLocal(candidate, entity), kit.getRef());
+        shard.tell(new RegisterCandidateLocal(entity), kit.getRef());
         kit.expectMsgClass(SuccessReply.class);
 
         // Verify the remote candidate becomes owner
         kit.expectMsgClass(SuccessReply.class);
 
         // Verify the remote candidate becomes owner
@@ -371,51 +347,42 @@ public class EntityOwnershipShardTest extends AbstractEntityOwnershipTest {
         verifyCommittedEntityCandidate(shard, ENTITY_TYPE, ENTITY_ID1, remoteMemberName1);
         verifyCommittedEntityCandidate(shard, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
         verifyOwner(shard, ENTITY_TYPE, ENTITY_ID1, remoteMemberName1);
         verifyCommittedEntityCandidate(shard, ENTITY_TYPE, ENTITY_ID1, remoteMemberName1);
         verifyCommittedEntityCandidate(shard, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
         verifyOwner(shard, ENTITY_TYPE, ENTITY_ID1, remoteMemberName1);
-        verify(candidate, never()).ownershipChanged(any(EntityOwnershipChange.class));
 
         // Add another remote candidate and verify ownership doesn't change
 
 
         // Add another remote candidate and verify ownership doesn't change
 
-        reset(candidate);
         String remoteMemberName2 = "remoteMember2";
         writeNode(ENTITY_OWNERS_PATH, entityOwnersWithCandidate(ENTITY_TYPE, ENTITY_ID1, remoteMemberName2), shardDataTree);
 
         verifyCommittedEntityCandidate(shard, ENTITY_TYPE, ENTITY_ID1, remoteMemberName2);
         Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS);
         verifyOwner(shard, ENTITY_TYPE, ENTITY_ID1, remoteMemberName1);
         String remoteMemberName2 = "remoteMember2";
         writeNode(ENTITY_OWNERS_PATH, entityOwnersWithCandidate(ENTITY_TYPE, ENTITY_ID1, remoteMemberName2), shardDataTree);
 
         verifyCommittedEntityCandidate(shard, ENTITY_TYPE, ENTITY_ID1, remoteMemberName2);
         Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS);
         verifyOwner(shard, ENTITY_TYPE, ENTITY_ID1, remoteMemberName1);
-        verify(candidate, never()).ownershipChanged(any(EntityOwnershipChange.class));
 
         // Remove the second remote candidate and verify ownership doesn't change
 
 
         // Remove the second remote candidate and verify ownership doesn't change
 
-        reset(candidate);
         deleteNode(candidatePath(ENTITY_TYPE, ENTITY_ID1, remoteMemberName2), shardDataTree);
 
         verifyEntityCandidateRemoved(shard, ENTITY_TYPE, ENTITY_ID1, remoteMemberName2);
         Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS);
         verifyOwner(shard, ENTITY_TYPE, ENTITY_ID1, remoteMemberName1);
         deleteNode(candidatePath(ENTITY_TYPE, ENTITY_ID1, remoteMemberName2), shardDataTree);
 
         verifyEntityCandidateRemoved(shard, ENTITY_TYPE, ENTITY_ID1, remoteMemberName2);
         Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS);
         verifyOwner(shard, ENTITY_TYPE, ENTITY_ID1, remoteMemberName1);
-        verify(candidate, never()).ownershipChanged(any(EntityOwnershipChange.class));
 
         // Remove the first remote candidate and verify the local candidate becomes owner
 
 
         // Remove the first remote candidate and verify the local candidate becomes owner
 
-        reset(candidate);
         deleteNode(candidatePath(ENTITY_TYPE, ENTITY_ID1, remoteMemberName1), shardDataTree);
 
         verifyEntityCandidateRemoved(shard, ENTITY_TYPE, ENTITY_ID1, remoteMemberName1);
         verifyOwner(shard, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
         deleteNode(candidatePath(ENTITY_TYPE, ENTITY_ID1, remoteMemberName1), shardDataTree);
 
         verifyEntityCandidateRemoved(shard, ENTITY_TYPE, ENTITY_ID1, remoteMemberName1);
         verifyOwner(shard, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
-        verify(candidate, timeout(5000)).ownershipChanged(ownershipChange(entity, false, true, true));
 
         // Add the second remote candidate back and verify ownership doesn't change
 
 
         // Add the second remote candidate back and verify ownership doesn't change
 
-        reset(candidate);
         writeNode(ENTITY_OWNERS_PATH, entityOwnersWithCandidate(ENTITY_TYPE, ENTITY_ID1, remoteMemberName2), shardDataTree);
 
         verifyCommittedEntityCandidate(shard, ENTITY_TYPE, ENTITY_ID1, remoteMemberName2);
         Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS);
         verifyOwner(shard, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
         writeNode(ENTITY_OWNERS_PATH, entityOwnersWithCandidate(ENTITY_TYPE, ENTITY_ID1, remoteMemberName2), shardDataTree);
 
         verifyCommittedEntityCandidate(shard, ENTITY_TYPE, ENTITY_ID1, remoteMemberName2);
         Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS);
         verifyOwner(shard, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
-        verify(candidate, never()).ownershipChanged(any(EntityOwnershipChange.class));
 
         // Unregister the local candidate and verify the second remote candidate becomes owner
 
 
         // Unregister the local candidate and verify the second remote candidate becomes owner
 
-        shard.tell(new UnregisterCandidateLocal(candidate, entity), kit.getRef());
+        shard.tell(new UnregisterCandidateLocal(entity), kit.getRef());
         kit.expectMsgClass(SuccessReply.class);
 
         verifyEntityCandidateRemoved(shard, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
         kit.expectMsgClass(SuccessReply.class);
 
         verifyEntityCandidateRemoved(shard, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
@@ -451,8 +418,6 @@ public class EntityOwnershipShardTest extends AbstractEntityOwnershipTest {
 
         kit.waitUntilLeader(leader);
 
 
         kit.waitUntilLeader(leader);
 
-        EntityOwnershipCandidate candidate = mock(EntityOwnershipCandidate.class);
-
         // Send PeerDown and PeerUp with no entities
 
         leader.tell(new PeerDown(peerMemberName2, peerId2.toString()), ActorRef.noSender());
         // Send PeerDown and PeerUp with no entities
 
         leader.tell(new PeerDown(peerMemberName2, peerId2.toString()), ActorRef.noSender());
@@ -460,7 +425,7 @@ public class EntityOwnershipShardTest extends AbstractEntityOwnershipTest {
 
         // Add candidates for entity1 with the local leader as the owner
 
 
         // Add candidates for entity1 with the local leader as the owner
 
-        leader.tell(new RegisterCandidateLocal(candidate, new Entity(ENTITY_TYPE, ENTITY_ID1)), kit.getRef());
+        leader.tell(new RegisterCandidateLocal(new Entity(ENTITY_TYPE, ENTITY_ID1)), kit.getRef());
         kit.expectMsgClass(SuccessReply.class);
         verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
 
         kit.expectMsgClass(SuccessReply.class);
         verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
 
@@ -485,7 +450,7 @@ public class EntityOwnershipShardTest extends AbstractEntityOwnershipTest {
         commitModification(leader, entityOwnersWithCandidate(ENTITY_TYPE, ENTITY_ID3, peerMemberName2), kit);
         verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID3, peerMemberName2);
 
         commitModification(leader, entityOwnersWithCandidate(ENTITY_TYPE, ENTITY_ID3, peerMemberName2), kit);
         verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID3, peerMemberName2);
 
-        leader.tell(new RegisterCandidateLocal(candidate, new Entity(ENTITY_TYPE, ENTITY_ID3)), kit.getRef());
+        leader.tell(new RegisterCandidateLocal(new Entity(ENTITY_TYPE, ENTITY_ID3)), kit.getRef());
         kit.expectMsgClass(SuccessReply.class);
         verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID3, LOCAL_MEMBER_NAME);
 
         kit.expectMsgClass(SuccessReply.class);
         verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID3, LOCAL_MEMBER_NAME);
 
@@ -630,31 +595,34 @@ public class EntityOwnershipShardTest extends AbstractEntityOwnershipTest {
         shard.tell(new PeerAddressResolved(leaderId.toString(), leader.path().toString()), ActorRef.noSender());
 
         Entity entity = new Entity(ENTITY_TYPE, ENTITY_ID1);
         shard.tell(new PeerAddressResolved(leaderId.toString(), leader.path().toString()), ActorRef.noSender());
 
         Entity entity = new Entity(ENTITY_TYPE, ENTITY_ID1);
-        EntityOwnershipCandidate candidate = mock(EntityOwnershipCandidate.class);
+        EntityOwnershipListener listener = mock(EntityOwnershipListener.class);
+
+        shard.tell(new RegisterListenerLocal(listener, ENTITY_TYPE), kit.getRef());
+        kit.expectMsgClass(SuccessReply.class);
 
         // Register local candidate
 
 
         // Register local candidate
 
-        shard.tell(new RegisterCandidateLocal(candidate, entity), kit.getRef());
+        shard.tell(new RegisterCandidateLocal(entity), kit.getRef());
         kit.expectMsgClass(SuccessReply.class);
         verifyCommittedEntityCandidate(shard, entity.getType(), entity.getId(), LOCAL_MEMBER_NAME);
         kit.expectMsgClass(SuccessReply.class);
         verifyCommittedEntityCandidate(shard, entity.getType(), entity.getId(), LOCAL_MEMBER_NAME);
-        verify(candidate, timeout(5000)).ownershipChanged(ownershipChange(entity, false, true, true));
-        reset(candidate);
+        verify(listener, timeout(5000)).ownershipChanged(ownershipChange(entity, false, true, true));
+        reset(listener);
 
         // Simulate a replicated commit from the leader to remove the local candidate that would occur after a
         // network partition is healed.
 
         leader.tell(new PeerDown(LOCAL_MEMBER_NAME, localId.toString()), ActorRef.noSender());
 
 
         // Simulate a replicated commit from the leader to remove the local candidate that would occur after a
         // network partition is healed.
 
         leader.tell(new PeerDown(LOCAL_MEMBER_NAME, localId.toString()), ActorRef.noSender());
 
-        verify(candidate, timeout(5000)).ownershipChanged(ownershipChange(entity, true, false, false));
+        verify(listener, timeout(5000)).ownershipChanged(ownershipChange(entity, true, false, false));
 
         // Since the the shard has a local candidate registered, it should re-add its candidate to the entity.
 
         verifyCommittedEntityCandidate(shard, entity.getType(), entity.getId(), LOCAL_MEMBER_NAME);
 
         // Since the the shard has a local candidate registered, it should re-add its candidate to the entity.
 
         verifyCommittedEntityCandidate(shard, entity.getType(), entity.getId(), LOCAL_MEMBER_NAME);
-        verify(candidate, timeout(5000)).ownershipChanged(ownershipChange(entity, false, true, true));
+        verify(listener, timeout(5000)).ownershipChanged(ownershipChange(entity, false, true, true));
 
         // Unregister the local candidate and verify it's removed and no re-added.
 
 
         // Unregister the local candidate and verify it's removed and no re-added.
 
-        shard.tell(new UnregisterCandidateLocal(candidate, entity), kit.getRef());
+        shard.tell(new UnregisterCandidateLocal(entity), kit.getRef());
         kit.expectMsgClass(SuccessReply.class);
 
         verifyNoEntityCandidate(shard, entity.getType(), entity.getId(), LOCAL_MEMBER_NAME);
         kit.expectMsgClass(SuccessReply.class);
 
         verifyNoEntityCandidate(shard, entity.getType(), entity.getId(), LOCAL_MEMBER_NAME);
@@ -675,7 +643,6 @@ public class EntityOwnershipShardTest extends AbstractEntityOwnershipTest {
         Entity entity3 = new Entity(ENTITY_TYPE, ENTITY_ID3);
         Entity entity4 = new Entity(otherEntityType, ENTITY_ID3);
         EntityOwnershipListener listener = mock(EntityOwnershipListener.class);
         Entity entity3 = new Entity(ENTITY_TYPE, ENTITY_ID3);
         Entity entity4 = new Entity(otherEntityType, ENTITY_ID3);
         EntityOwnershipListener listener = mock(EntityOwnershipListener.class);
-        EntityOwnershipCandidate candidate = mock(EntityOwnershipCandidate.class);
 
         // Register listener
 
 
         // Register listener
 
@@ -684,12 +651,12 @@ public class EntityOwnershipShardTest extends AbstractEntityOwnershipTest {
 
         // Register a couple candidates for the desired entity type and verify listener is notified.
 
 
         // Register a couple candidates for the desired entity type and verify listener is notified.
 
-        shard.tell(new RegisterCandidateLocal(candidate, entity1), kit.getRef());
+        shard.tell(new RegisterCandidateLocal(entity1), kit.getRef());
         kit.expectMsgClass(SuccessReply.class);
 
         verify(listener, timeout(5000)).ownershipChanged(ownershipChange(entity1, false, true, true));
 
         kit.expectMsgClass(SuccessReply.class);
 
         verify(listener, timeout(5000)).ownershipChanged(ownershipChange(entity1, false, true, true));
 
-        shard.tell(new RegisterCandidateLocal(candidate, entity2), kit.getRef());
+        shard.tell(new RegisterCandidateLocal(entity2), kit.getRef());
         kit.expectMsgClass(SuccessReply.class);
 
         verify(listener, timeout(5000)).ownershipChanged(ownershipChange(entity2, false, true, true));
         kit.expectMsgClass(SuccessReply.class);
 
         verify(listener, timeout(5000)).ownershipChanged(ownershipChange(entity2, false, true, true));
@@ -697,7 +664,7 @@ public class EntityOwnershipShardTest extends AbstractEntityOwnershipTest {
 
         // Register another candidate for another entity type and verify listener is not notified.
 
 
         // Register another candidate for another entity type and verify listener is not notified.
 
-        shard.tell(new RegisterCandidateLocal(candidate, entity4), kit.getRef());
+        shard.tell(new RegisterCandidateLocal(entity4), kit.getRef());
         kit.expectMsgClass(SuccessReply.class);
 
         Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS);
         kit.expectMsgClass(SuccessReply.class);
 
         Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS);
@@ -712,7 +679,7 @@ public class EntityOwnershipShardTest extends AbstractEntityOwnershipTest {
 
         // Unregister the local candidate for entity1 and verify listener is notified
 
 
         // Unregister the local candidate for entity1 and verify listener is notified
 
-        shard.tell(new UnregisterCandidateLocal(candidate, entity1), kit.getRef());
+        shard.tell(new UnregisterCandidateLocal(entity1), kit.getRef());
         kit.expectMsgClass(SuccessReply.class);
 
         verify(listener, timeout(5000)).ownershipChanged(ownershipChange(entity1, true, false, true));
         kit.expectMsgClass(SuccessReply.class);
 
         verify(listener, timeout(5000)).ownershipChanged(ownershipChange(entity1, true, false, true));
@@ -723,7 +690,7 @@ public class EntityOwnershipShardTest extends AbstractEntityOwnershipTest {
         shard.tell(new UnregisterListenerLocal(listener, ENTITY_TYPE), kit.getRef());
         kit.expectMsgClass(SuccessReply.class);
 
         shard.tell(new UnregisterListenerLocal(listener, ENTITY_TYPE), kit.getRef());
         kit.expectMsgClass(SuccessReply.class);
 
-        shard.tell(new RegisterCandidateLocal(candidate, entity3), kit.getRef());
+        shard.tell(new RegisterCandidateLocal(entity3), kit.getRef());
         kit.expectMsgClass(SuccessReply.class);
 
         verifyOwner(shard, ENTITY_TYPE, entity3.getId(), LOCAL_MEMBER_NAME);
         kit.expectMsgClass(SuccessReply.class);
 
         verifyOwner(shard, ENTITY_TYPE, entity3.getId(), LOCAL_MEMBER_NAME);
@@ -732,7 +699,7 @@ public class EntityOwnershipShardTest extends AbstractEntityOwnershipTest {
 
         // Re-register the listener and verify it gets notified of currently owned entities
 
 
         // Re-register the listener and verify it gets notified of currently owned entities
 
-        reset(listener, candidate);
+        reset(listener);
 
         shard.tell(new RegisterListenerLocal(listener, ENTITY_TYPE), kit.getRef());
         kit.expectMsgClass(SuccessReply.class);
 
         shard.tell(new RegisterListenerLocal(listener, ENTITY_TYPE), kit.getRef());
         kit.expectMsgClass(SuccessReply.class);
@@ -742,8 +709,6 @@ public class EntityOwnershipShardTest extends AbstractEntityOwnershipTest {
         Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
         verify(listener, never()).ownershipChanged(ownershipChange(entity4));
         verify(listener, never()).ownershipChanged(ownershipChange(entity1));
         Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
         verify(listener, never()).ownershipChanged(ownershipChange(entity4));
         verify(listener, never()).ownershipChanged(ownershipChange(entity1));
-        verify(candidate, never()).ownershipChanged(ownershipChange(entity2));
-        verify(candidate, never()).ownershipChanged(ownershipChange(entity3));
     }
 
     private void commitModification(TestActorRef<EntityOwnershipShard> shard, NormalizedNode<?, ?> node,
     }
 
     private void commitModification(TestActorRef<EntityOwnershipShard> shard, NormalizedNode<?, ?> node,
index d0b47aebdca04478124b068b265e852206062fde..9e5e57db112cda2830175ee6f8c0eb53dbe45a9b 100644 (file)
@@ -12,13 +12,14 @@ import com.google.common.util.concurrent.Futures;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicLong;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.clustering.CandidateAlreadyRegisteredException;
 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
 import java.util.concurrent.atomic.AtomicLong;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.clustering.CandidateAlreadyRegisteredException;
 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidate;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipChange;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipChange;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
@@ -50,9 +51,8 @@ public class CarProvider implements CarService {
 
     private static final String ENTITY_TYPE = "cars";
 
 
     private static final String ENTITY_TYPE = "cars";
 
-
-    private final CarEntityOwnershipCandidate ownershipCandidate = new CarEntityOwnershipCandidate();
-
+    private final CarEntityOwnershipListener ownershipListener = new CarEntityOwnershipListener();
+    private final AtomicBoolean registeredListener = new AtomicBoolean();
 
     private volatile Thread testThread;
     private volatile boolean stopThread;
 
     private volatile Thread testThread;
     private volatile boolean stopThread;
@@ -156,9 +156,13 @@ public class CarProvider implements CarService {
 
     @Override
     public Future<RpcResult<Void>> registerOwnership(RegisterOwnershipInput input) {
 
     @Override
     public Future<RpcResult<Void>> registerOwnership(RegisterOwnershipInput input) {
+        if(registeredListener.compareAndSet(false, true)) {
+            ownershipService.registerListener(ENTITY_TYPE, ownershipListener);
+        }
+
         Entity entity = new Entity(ENTITY_TYPE, input.getCarId());
         try {
         Entity entity = new Entity(ENTITY_TYPE, input.getCarId());
         try {
-            ownershipService.registerCandidate(entity, ownershipCandidate);
+            ownershipService.registerCandidate(entity);
         } catch (CandidateAlreadyRegisteredException e) {
             return RpcResultBuilder.<Void>failed().withError(ErrorType.APPLICATION,
                     "Could not register for car " + input.getCarId(), e).buildFuture();
         } catch (CandidateAlreadyRegisteredException e) {
             return RpcResultBuilder.<Void>failed().withError(ErrorType.APPLICATION,
                     "Could not register for car " + input.getCarId(), e).buildFuture();
@@ -172,7 +176,7 @@ public class CarProvider implements CarService {
         return RpcResultBuilder.<Void>success().buildFuture();
     }
 
         return RpcResultBuilder.<Void>success().buildFuture();
     }
 
-    private static class CarEntityOwnershipCandidate implements EntityOwnershipCandidate {
+    private static class CarEntityOwnershipListener implements EntityOwnershipListener {
         @Override
         public void ownershipChanged(EntityOwnershipChange ownershipChange) {
             LOG.info("ownershipChanged: {}", ownershipChange);
         @Override
         public void ownershipChanged(EntityOwnershipChange ownershipChange) {
             LOG.info("ownershipChanged: {}", ownershipChange);