--- /dev/null
+/*
+ * Copyright (c) 2015 Brocade Communications Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.common.api.clustering;
+
+import com.google.common.base.Preconditions;
+import javax.annotation.Nonnull;
+
+/**
+ * A DTO that encapsulates an ownership change for an entity.
+ *
+ * @author Thomas Pantelis
+ */
+public class EntityOwnershipChange {
+ private final Entity entity;
+ private final boolean wasOwner;
+ private final boolean isOwner;
+ private final boolean hasOwner;
+
+ public EntityOwnershipChange(@Nonnull Entity entity, boolean wasOwner, boolean isOwner, boolean hasOwner) {
+ this.entity = Preconditions.checkNotNull(entity, "entity can't be null");
+ this.wasOwner = wasOwner;
+ this.isOwner = isOwner;
+ this.hasOwner = hasOwner;
+ }
+
+ /**
+ * Returns the entity whose ownership status changed.
+ * @return the entity
+ */
+ @Nonnull public Entity getEntity() {
+ return entity;
+ }
+
+ /**
+ * Returns the previous ownership status of the entity for this process instance.
+ * @return true if this process was the owner of the entity at the time this notification was generated
+ */
+ public boolean wasOwner() {
+ return wasOwner;
+ }
+
+ /**
+ * Returns the current ownership status of the entity for this process instance.
+ * @return true if this process is now the owner of the entity
+ */
+ public boolean isOwner() {
+ return isOwner;
+ }
+
+ /**
+ * Returns the current ownership status of the entity across all process instances.
+ * @return true if the entity has an owner which may or may not be this process. If false, then
+ * the entity has no candidates and thus no owner.
+ */
+ public boolean hasOwner() {
+ return hasOwner;
+ }
+
+ @Override
+ public String toString() {
+ return "EntityOwnershipChanged [entity=" + entity + ", wasOwner=" + wasOwner + ", isOwner=" + isOwner
+ + ", hasOwner=" + hasOwner + "]";
+ }
+}
public interface EntityOwnershipListener {
/**
- * A notification that is generated when the ownership status for a given entity changes in the current process.
+ * A notification that is generated when the ownership status of an entity changes.
*
- * @param entity the entity whose ownership status has changed
- * @param wasOwner true if this process was the owner of the given entity right before this notification
- * was generated
- * @param isOwner true if this process now owns the given entity
+ * The following outlines valid combinations of the ownership status flags in the EntityOwnershipChange
+ * parameter and their meanings:
+ * <ul>
+ * <li><b>wasOwner = false, isOwner = true, hasOwner = true</b> - this process has been granted ownership</li>
+ * <li><b>wasOwner = true, isOwner = false, hasOwner = true</b> - this process was the owner but ownership
+ * transitioned to another process</li>
+ * <li><b>wasOwner = false, isOwner = false, hasOwner = true</b> - ownership transitioned to another process
+ * and this process was not the previous owner</li>
+ * <li><b>wasOwner = false, isOwner = false, hasOwner = false</b> - the entity no longer has any candidates and
+ * thus no owner and this process was not the previous owner</li>
+ * <li><b>wasOwner = true, isOwner = false, hasOwner = false</b> - the entity no longer has any candidates and
+ * thus no owner and this process was the previous owner</li>
+ * </ul>
+ * @param ownershipChange contains the entity and its ownership status flags
*/
- void ownershipChanged(Entity entity, boolean wasOwner, boolean isOwner);
+ void ownershipChanged(EntityOwnershipChange ownershipChange);
}
if(!Objects.equal(origOwner, newOwner)) {
boolean isOwner = Objects.equal(localMemberName, newOwner);
boolean wasOwner = Objects.equal(localMemberName, origOwner);
- if(isOwner || wasOwner) {
- Entity entity = createEntity(change.getRootPath());
+ boolean hasOwner = newOwner != null && !newOwner.toString().isEmpty();
- LOG.debug("{}: Calling notifyEntityOwnershipListeners: entity: {}, wasOwner: {}, isOwner: {}",
- logId(), entity, wasOwner, isOwner);
+ Entity entity = createEntity(change.getRootPath());
- listenerSupport.notifyEntityOwnershipListeners(entity, wasOwner, isOwner);
- }
+ LOG.debug("{}: Calling notifyEntityOwnershipListeners: entity: {}, wasOwner: {}, isOwner: {}, hasOwner: {}",
+ logId(), entity, wasOwner, isOwner, hasOwner);
+
+ listenerSupport.notifyEntityOwnershipListeners(entity, wasOwner, isOwner, hasOwner);
}
}
}
import akka.japi.Creator;
import com.google.common.base.Preconditions;
import org.opendaylight.controller.cluster.common.actor.AbstractUntypedActor;
-import org.opendaylight.controller.cluster.datastore.entityownership.messages.EntityOwnershipChanged;
+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.slf4j.LoggerFactory;
@Override
protected void handleReceive(Object message) {
- if(message instanceof EntityOwnershipChanged) {
- onEntityOwnershipChanged((EntityOwnershipChanged)message);
+ if(message instanceof EntityOwnershipChange) {
+ onEntityOwnershipChanged((EntityOwnershipChange)message);
}
}
- private void onEntityOwnershipChanged(EntityOwnershipChanged change) {
+ private void onEntityOwnershipChanged(EntityOwnershipChange change) {
LOG.debug("Notifying EntityOwnershipListener {}: {}", listener, change);
try {
- listener.ownershipChanged(change.getEntity(), change.wasOwner(), change.isOwner());
+ listener.ownershipChanged(change);
} catch (Exception e) {
LOG.error("Error notifying listener {}", listener, e);
}
import java.util.Collection;
import java.util.IdentityHashMap;
import java.util.Map;
-import org.opendaylight.controller.cluster.datastore.entityownership.messages.EntityOwnershipChanged;
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.slf4j.LoggerFactory;
removeListener(listener, entityType, entityTypeListenerMap);
}
- void notifyEntityOwnershipListeners(Entity entity, boolean wasOwner, boolean isOwner) {
- notifyListeners(entity, entity, wasOwner, isOwner, entityListenerMap);
- notifyListeners(entity, entity.getType(), wasOwner, isOwner, entityTypeListenerMap);
+ 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);
}
- void notifyEntityOwnershipListener(Entity entity, boolean wasOwner, boolean isOwner,
+ void notifyEntityOwnershipListener(Entity entity, boolean wasOwner, boolean isOwner, boolean hasOwner,
EntityOwnershipListener listener) {
- notifyListeners(entity, wasOwner, isOwner, Arrays.asList(listener));
+ notifyListeners(entity, wasOwner, isOwner, hasOwner, Arrays.asList(listener));
}
- private <T> void notifyListeners(Entity entity, T mapKey, boolean wasOwner, boolean isOwner,
+ private <T> void notifyListeners(Entity entity, T mapKey, boolean wasOwner, boolean isOwner, boolean hasOwner,
Multimap<T, EntityOwnershipListener> listenerMap) {
Collection<EntityOwnershipListener> listeners = listenerMap.get(mapKey);
if(!listeners.isEmpty()) {
- notifyListeners(entity, wasOwner, isOwner, listeners);
+ notifyListeners(entity, wasOwner, isOwner, hasOwner, listeners);
}
}
- private void notifyListeners(Entity entity, boolean wasOwner, boolean isOwner,
+ private void notifyListeners(Entity entity, boolean wasOwner, boolean isOwner, boolean hasOwner,
Collection<EntityOwnershipListener> listeners) {
- EntityOwnershipChanged changed = new EntityOwnershipChanged(entity, wasOwner, isOwner);
+ EntityOwnershipChange changed = new EntityOwnershipChange(entity, wasOwner, isOwner, hasOwner);
for(EntityOwnershipListener listener: listeners) {
ActorRef listenerActor = listenerActorFor(listener);
if(registerListener.getEntityType().equals(entityType)) {
Entity entity = new Entity(entityType,
(YangInstanceIdentifier) entityNode.getChild(ENTITY_ID_NODE_ID).get().getValue());
- listenerSupport.notifyEntityOwnershipListener(entity, false, true, registerListener.getListener());
+ listenerSupport.notifyEntityOwnershipListener(entity, false, true, true, registerListener.getListener());
}
}
});
+++ /dev/null
-/*
- * Copyright (c) 2015 Brocade Communications Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.cluster.datastore.entityownership.messages;
-
-import com.google.common.base.Preconditions;
-import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
-
-/**
- * Message encapsulating an entity ownership change.
- *
- * @author Thomas Pantelis
- */
-public class EntityOwnershipChanged {
- private final Entity entity;
- private final boolean wasOwner;
- private final boolean isOwner;
-
- public EntityOwnershipChanged(Entity entity, boolean wasOwner, boolean isOwner) {
- this.entity = Preconditions.checkNotNull(entity, "entity can't be null");
- this.wasOwner = wasOwner;
- this.isOwner = isOwner;
- }
-
- public Entity getEntity() {
- return entity;
- }
-
- public boolean wasOwner() {
- return wasOwner;
- }
-
- public boolean isOwner() {
- return isOwner;
- }
-
- @Override
- public String toString() {
- return "EntityOwnershipChanged [entity=" + entity + ", wasOwner=" + wasOwner + ", isOwner=" + isOwner + "]";
- }
-}
import com.google.common.base.Stopwatch;
import com.google.common.util.concurrent.Uninterruptibles;
import java.util.concurrent.TimeUnit;
+import org.hamcrest.Description;
import org.junit.Assert;
+import org.mockito.ArgumentMatcher;
+import org.mockito.Matchers;
import org.opendaylight.controller.cluster.datastore.AbstractActorTest;
import org.opendaylight.controller.cluster.datastore.ShardDataTree;
+import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipChange;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.clustering.entity.owners.rev150804.EntityOwners;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.clustering.entity.owners.rev150804.entity.owners.EntityType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.clustering.entity.owners.rev150804.entity.owners.entity.type.entity.Candidate;
shardDataTree.getDataTree().commit(candidate);
shardDataTree.notifyListeners(candidate);
}
+
+ static EntityOwnershipChange ownershipChange(final Entity expEntity, final boolean expWasOwner,
+ final boolean expIsOwner, final boolean expHasOwner) {
+ return Matchers.argThat(new ArgumentMatcher<EntityOwnershipChange>() {
+ @Override
+ public boolean matches(Object argument) {
+ EntityOwnershipChange change = (EntityOwnershipChange) argument;
+ return expEntity.equals(change.getEntity()) && expWasOwner == change.wasOwner() &&
+ expIsOwner == change.isOwner() && expHasOwner == change.hasOwner();
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendValue(new EntityOwnershipChange(expEntity, expWasOwner, expIsOwner, expHasOwner));
+ }
+ });
+ }
+
+ static EntityOwnershipChange ownershipChange(final Entity expEntity) {
+ return Matchers.argThat(new ArgumentMatcher<EntityOwnershipChange>() {
+ @Override
+ public boolean matches(Object argument) {
+ EntityOwnershipChange change = (EntityOwnershipChange) argument;
+ return expEntity.equals(change.getEntity());
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendValue(new EntityOwnershipChange(expEntity, false, false, false));
+ }
+ });
+ }
}
package org.opendaylight.controller.cluster.datastore.entityownership;
import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
+import static org.opendaylight.controller.cluster.datastore.entityownership.AbstractEntityOwnershipTest.ownershipChange;
import static org.opendaylight.controller.cluster.datastore.entityownership.EntityOwnersModel.CANDIDATE_NAME_NODE_ID;
import static org.opendaylight.controller.cluster.datastore.entityownership.EntityOwnersModel.entityPath;
import akka.actor.ActorSystem;
@Mock
private EntityOwnershipCandidate follower2MockCandidate;
+ @Mock
+ private EntityOwnershipCandidate leaderMockListener;
+
+ @Mock
+ private EntityOwnershipCandidate leaderMockListener2;
+
+ @Mock
+ private EntityOwnershipCandidate follower1MockListener;
+
+ @Mock
+ private EntityOwnershipCandidate follower2MockListener;
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
public void test() throws Exception {
initDatastores("test");
+ leaderEntityOwnershipService.registerListener(ENTITY_TYPE1, leaderMockListener);
+ leaderEntityOwnershipService.registerListener(ENTITY_TYPE2, leaderMockListener2);
+ follower1EntityOwnershipService.registerListener(ENTITY_TYPE1, follower1MockListener);
+
// Register leader candidate for entity1 and verify it becomes owner
leaderEntityOwnershipService.registerCandidate(ENTITY1, leaderMockCandidate);
- verify(leaderMockCandidate, timeout(5000)).ownershipChanged(ENTITY1, false, true);
- reset(leaderMockCandidate);
+ 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);
- verify(leaderMockCandidate, timeout(5000)).ownershipChanged(ENTITY1_2, false, true);
- reset(leaderMockCandidate);
+ 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);
verifyCandidates(leaderDistributedDataStore, ENTITY1, "member-1", "member-2");
verifyOwner(leaderDistributedDataStore, ENTITY1, "member-1");
- verify(follower1MockCandidate, never()).ownershipChanged(any(Entity.class), anyBoolean(), anyBoolean());
+ verify(leaderMockListener, timeout(300).never()).ownershipChanged(ownershipChange(ENTITY1));
+ verify(follower1MockListener, timeout(300).never()).ownershipChanged(ownershipChange(ENTITY1));
// Register follower1 candidate for entity2 and verify it becomes owner
follower1EntityOwnershipService.registerCandidate(ENTITY2, follower1MockCandidate);
- verify(follower1MockCandidate, timeout(5000)).ownershipChanged(ENTITY2, false, true);
- reset(follower1MockCandidate);
+ verify(follower1MockCandidate, 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);
follower2EntityOwnershipService.registerCandidate(ENTITY2, follower2MockCandidate);
verifyCandidates(leaderDistributedDataStore, ENTITY2, "member-2", "member-3");
verifyOwner(leaderDistributedDataStore, ENTITY2, "member-2");
- verify(follower2MockCandidate, never()).ownershipChanged(any(Entity.class), anyBoolean(), anyBoolean());
// Unregister follower1 candidate for entity2 and verify follower2 becomes owner
follower1EntityOwnershipService.unregisterCandidate(ENTITY2, follower1MockCandidate);
- verify(follower2MockCandidate, timeout(5000)).ownershipChanged(ENTITY2, 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));
+ verify(leaderMockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY2, false, false, true));
+ verifyCandidates(leaderDistributedDataStore, ENTITY2, "member-3");
// Register follower1 candidate for entity3 and verify it becomes owner
follower1EntityOwnershipService.registerCandidate(ENTITY3, follower1MockCandidate);
- verify(follower1MockCandidate, timeout(5000)).ownershipChanged(ENTITY3, 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));
+ verify(leaderMockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY3, false, false, true));
// Register follower2 candidate for entity4 and verify it becomes owner
follower2EntityOwnershipService.registerCandidate(ENTITY4, follower2MockCandidate);
- verify(follower2MockCandidate, timeout(5000)).ownershipChanged(ENTITY4, false, true);
- reset(follower2MockCandidate);
+ 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);
// Register follower1 candidate for entity4 and verify it gets added but doesn't become owner
follower1EntityOwnershipService.registerCandidate(ENTITY4, follower1MockCandidate);
verifyCandidates(leaderDistributedDataStore, ENTITY4, "member-3", "member-2");
verifyOwner(leaderDistributedDataStore, ENTITY4, "member-3");
- verify(follower1MockCandidate, never()).ownershipChanged(any(Entity.class), anyBoolean(), anyBoolean());
// Shutdown follower2 and verify it's owned entities (entity 2 & 4) get re-assigned
- reset(follower1MockCandidate);
+ reset(leaderMockListener, follower1MockListener);
JavaTestKit.shutdownActorSystem(follower2System);
- verify(follower1MockCandidate, timeout(15000)).ownershipChanged(ENTITY4, false, true);
+ verify(follower1MockListener, timeout(15000)).ownershipChanged(ownershipChange(ENTITY4, false, true, true));
+ verify(leaderMockListener, timeout(15000)).ownershipChanged(ownershipChange(ENTITY4, false, false, true));
+ verify(leaderMockListener, timeout(15000)).ownershipChanged(ownershipChange(ENTITY2, false, false, false));
verifyOwner(leaderDistributedDataStore, ENTITY2, ""); // no other candidate
// Register leader candidate for entity2 and verify it becomes owner
leaderEntityOwnershipService.registerCandidate(ENTITY2, leaderMockCandidate);
- verify(leaderMockCandidate, timeout(5000)).ownershipChanged(ENTITY2, false, true);
+ 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);
verifyOwner(leaderDistributedDataStore, ENTITY2, "");
+ verify(leaderMockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY2, true, false, false));
+ verify(follower1MockListener, timeout(5000)).ownershipChanged(ownershipChange(ENTITY2, false, false, false));
}
private void verifyCandidates(DistributedDataStore dataStore, Entity entity, String... expCandidates) throws Exception {
public void testOnDataTreeChanged() throws Exception {
writeNode(ENTITY_OWNERS_PATH, entityOwnersWithCandidate(ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME));
writeNode(ENTITY_OWNERS_PATH, entityOwnersWithCandidate(ENTITY_TYPE, ENTITY_ID2, LOCAL_MEMBER_NAME));
- verify(mockListenerSupport, never()).notifyEntityOwnershipListeners(any(Entity.class), anyBoolean(), anyBoolean());
+ verify(mockListenerSupport, never()).notifyEntityOwnershipListeners(any(Entity.class), anyBoolean(),
+ anyBoolean(), anyBoolean());
+
+ // Write local member as owner for entity 1
writeNode(entityPath(ENTITY_TYPE, ENTITY_ID1), entityEntryWithOwner(ENTITY_ID1, LOCAL_MEMBER_NAME));
- verify(mockListenerSupport).notifyEntityOwnershipListeners(ENTITY1, false, true);
+ verify(mockListenerSupport).notifyEntityOwnershipListeners(ENTITY1, false, true, true);
+
+ // Add remote member 1 as candidate for entity 1 - listener support should not get notified
reset(mockListenerSupport);
writeNode(ENTITY_OWNERS_PATH, entityOwnersWithCandidate(ENTITY_TYPE, ENTITY_ID1, REMOTE_MEMBER_NAME1));
- verify(mockListenerSupport, never()).notifyEntityOwnershipListeners(any(Entity.class), anyBoolean(), anyBoolean());
+ verify(mockListenerSupport, never()).notifyEntityOwnershipListeners(any(Entity.class), anyBoolean(),
+ anyBoolean(), anyBoolean());
+
+ // Change owner to remote member 1 for entity 1
reset(mockListenerSupport);
writeNode(entityPath(ENTITY_TYPE, ENTITY_ID1), entityEntryWithOwner(ENTITY_ID1, REMOTE_MEMBER_NAME1));
- verify(mockListenerSupport).notifyEntityOwnershipListeners(ENTITY1, true, false);
+ verify(mockListenerSupport).notifyEntityOwnershipListeners(ENTITY1, true, false, true);
+
+ // Change owner to remote member 2 for entity 1
reset(mockListenerSupport);
writeNode(entityPath(ENTITY_TYPE, ENTITY_ID1), entityEntryWithOwner(ENTITY_ID1, REMOTE_MEMBER_NAME2));
- verify(mockListenerSupport, never()).notifyEntityOwnershipListeners(any(Entity.class), anyBoolean(), anyBoolean());
+ verify(mockListenerSupport).notifyEntityOwnershipListeners(ENTITY1, false, false, true);
+
+ // Clear the owner for entity 1
+
+ reset(mockListenerSupport);
+ writeNode(entityPath(ENTITY_TYPE, ENTITY_ID1), entityEntryWithOwner(ENTITY_ID1, ""));
+ verify(mockListenerSupport).notifyEntityOwnershipListeners(ENTITY1, false, false, false);
+
+ // Change owner to the local member for entity 1
writeNode(entityPath(ENTITY_TYPE, ENTITY_ID1), entityEntryWithOwner(ENTITY_ID1, LOCAL_MEMBER_NAME));
- verify(mockListenerSupport).notifyEntityOwnershipListeners(ENTITY1, false, true);
+ verify(mockListenerSupport).notifyEntityOwnershipListeners(ENTITY1, false, true, true);
+
+ // Change owner to remote member 2 for entity 2
reset(mockListenerSupport);
writeNode(entityPath(ENTITY_TYPE, ENTITY_ID2), entityEntryWithOwner(ENTITY_ID2, REMOTE_MEMBER_NAME1));
- verify(mockListenerSupport, never()).notifyEntityOwnershipListeners(any(Entity.class), anyBoolean(), anyBoolean());
+ verify(mockListenerSupport).notifyEntityOwnershipListeners(ENTITY2, false, false, true);
+
+ // Change owner to the local member for entity 2
reset(mockListenerSupport);
writeNode(entityPath(ENTITY_TYPE, ENTITY_ID2), entityEntryWithOwner(ENTITY_ID2, LOCAL_MEMBER_NAME));
- verify(mockListenerSupport).notifyEntityOwnershipListeners(ENTITY2, false, true);
+ verify(mockListenerSupport).notifyEntityOwnershipListeners(ENTITY2, false, true, true);
+
+ // Write local member owner for entity 2 again - expect no change
reset(mockListenerSupport);
writeNode(entityPath(ENTITY_TYPE, ENTITY_ID2), entityEntryWithOwner(ENTITY_ID2, LOCAL_MEMBER_NAME));
- verify(mockListenerSupport, never()).notifyEntityOwnershipListeners(any(Entity.class), anyBoolean(), anyBoolean());
+ verify(mockListenerSupport, never()).notifyEntityOwnershipListeners(any(Entity.class), anyBoolean(),
+ anyBoolean(), anyBoolean());
+
+ // Clear the owner for entity 2
reset(mockListenerSupport);
writeNode(entityPath(ENTITY_TYPE, ENTITY_ID2), entityEntryWithOwner(ENTITY_ID2, null));
- verify(mockListenerSupport).notifyEntityOwnershipListeners(ENTITY2, true, false);
+ verify(mockListenerSupport).notifyEntityOwnershipListeners(ENTITY2, true, false, false);
+
+ // Clear the owner for entity 2 again - expect no change
+
+ reset(mockListenerSupport);
+ writeNode(entityPath(ENTITY_TYPE, ENTITY_ID2), entityEntryWithOwner(ENTITY_ID2, null));
+ verify(mockListenerSupport, never()).notifyEntityOwnershipListeners(any(Entity.class), anyBoolean(),
+ anyBoolean(), anyBoolean());
}
private void writeNode(YangInstanceIdentifier path, NormalizedNode<?, ?> node) throws DataValidationFailedException {
AbstractEntityOwnershipTest.writeNode(path, node, shardDataTree);
}
-
- private void deleteNode(YangInstanceIdentifier path) throws DataValidationFailedException {
- AbstractEntityOwnershipTest.deleteNode(path, shardDataTree);
- }
}
import akka.testkit.TestActorRef;
import org.junit.After;
import org.junit.Test;
-import org.opendaylight.controller.cluster.datastore.AbstractActorTest;
-import org.opendaylight.controller.cluster.datastore.entityownership.messages.EntityOwnershipChanged;
import org.opendaylight.controller.cluster.raft.TestActorFactory;
import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
+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;
*
* @author Thomas Pantelis
*/
-public class EntityOwnershipListenerActorTest extends AbstractActorTest {
+public class EntityOwnershipListenerActorTest extends AbstractEntityOwnershipTest {
private final TestActorFactory actorFactory = new TestActorFactory(getSystem());
@After
Entity entity = new Entity("test", YangInstanceIdentifier.of(QName.create("test", "id1")));
boolean wasOwner = false;
boolean isOwner = true;
- listenerActor.tell(new EntityOwnershipChanged(entity, wasOwner, isOwner), ActorRef.noSender());
+ boolean hasOwner = true;
+ listenerActor.tell(new EntityOwnershipChange(entity, wasOwner, isOwner, hasOwner), ActorRef.noSender());
- verify(mockListener, timeout(5000)).ownershipChanged(entity, wasOwner, isOwner);
+ verify(mockListener, timeout(5000)).ownershipChanged(ownershipChange(entity, wasOwner, isOwner, hasOwner));
}
@Test
EntityOwnershipListener mockListener = mock(EntityOwnershipListener.class);
Entity entity1 = new Entity("test", YangInstanceIdentifier.of(QName.create("test", "id1")));
- doThrow(new RuntimeException("mock")).when(mockListener).ownershipChanged(entity1, false, true);
+ doThrow(new RuntimeException("mock")).when(mockListener).ownershipChanged(ownershipChange(entity1, false, true, true));
Entity entity2 = new Entity("test", YangInstanceIdentifier.of(QName.create("test", "id2")));
- doNothing().when(mockListener).ownershipChanged(entity2, true, false);
+ doNothing().when(mockListener).ownershipChanged(ownershipChange(entity2, true, false, false));
TestActorRef<EntityOwnershipListenerActor> listenerActor = actorFactory.createTestActor(
EntityOwnershipListenerActor.props(mockListener), actorFactory.generateActorId("listener"));
- listenerActor.tell(new EntityOwnershipChanged(entity1, false, true), ActorRef.noSender());
- listenerActor.tell(new EntityOwnershipChanged(entity2, true, false), ActorRef.noSender());
+ listenerActor.tell(new EntityOwnershipChange(entity1, false, true, true), ActorRef.noSender());
+ listenerActor.tell(new EntityOwnershipChange(entity2, true, false, false), ActorRef.noSender());
- verify(mockListener, timeout(5000)).ownershipChanged(entity2, true, false);
+ verify(mockListener, timeout(5000)).ownershipChanged(ownershipChange(entity2, true, false, false));
}
}
package org.opendaylight.controller.cluster.datastore.entityownership;
import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import org.opendaylight.controller.cluster.datastore.AbstractActorTest;
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;
*
* @author Thomas Pantelis
*/
-public class EntityOwnershipListenerSupportTest extends AbstractActorTest {
+public class EntityOwnershipListenerSupportTest extends AbstractEntityOwnershipTest {
private final TestActorFactory actorFactory = new TestActorFactory(getSystem());
private ActorContext actorContext;
// Notify entity1 changed and verify listeners are notified.
- support.notifyEntityOwnershipListeners(entity1, false, true);
+ support.notifyEntityOwnershipListeners(entity1, false, true, true);
- verify(mockListener1, timeout(5000)).ownershipChanged(entity1, false, true);
- verify(mockListener2, timeout(5000)).ownershipChanged(entity1, false, true);
- verify(mockListener3, timeout(5000)).ownershipChanged(entity1, false, 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());
// Notify entity2 changed and verify only mockListener1 and mockListener3 are notified.
- support.notifyEntityOwnershipListeners(entity2, false, true);
+ support.notifyEntityOwnershipListeners(entity2, false, false, false);
- verify(mockListener1, timeout(5000)).ownershipChanged(entity2, false, true);
- verify(mockListener3, timeout(5000)).ownershipChanged(entity2, false, 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(eq(entity2), anyBoolean(), anyBoolean());
+ verify(mockListener2, never()).ownershipChanged(ownershipChange(entity2));
assertEquals("# of listener actors", 3, actorContext.children().size());
// Notify entity3 changed and verify only mockListener3 is notified.
- support.notifyEntityOwnershipListeners(entity3, false, true);
+ support.notifyEntityOwnershipListeners(entity3, false, true, true);
- verify(mockListener3, timeout(5000)).ownershipChanged(entity3, false, true);
+ verify(mockListener3, timeout(5000)).ownershipChanged(ownershipChange(entity3, false, true, true));
Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
- verify(mockListener1, never()).ownershipChanged(eq(entity3), anyBoolean(), anyBoolean());
- verify(mockListener2, never()).ownershipChanged(eq(entity3), anyBoolean(), anyBoolean());
+ verify(mockListener1, never()).ownershipChanged(ownershipChange(entity3));
+ verify(mockListener2, never()).ownershipChanged(ownershipChange(entity3));
// Notify entity4 changed and verify no listeners are notified.
- support.notifyEntityOwnershipListeners(entity4, false, true);
+ support.notifyEntityOwnershipListeners(entity4, true, false, true);
Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
- verify(mockListener1, never()).ownershipChanged(eq(entity4), anyBoolean(), anyBoolean());
- verify(mockListener2, never()).ownershipChanged(eq(entity4), anyBoolean(), anyBoolean());
- verify(mockListener3, never()).ownershipChanged(eq(entity4), anyBoolean(), anyBoolean());
+ verify(mockListener1, never()).ownershipChanged(ownershipChange(entity4));
+ verify(mockListener2, never()).ownershipChanged(ownershipChange(entity4));
+ verify(mockListener3, never()).ownershipChanged(ownershipChange(entity4));
// Notify entity5 changed and verify no listener is notified.
- support.notifyEntityOwnershipListeners(entity5, false, true);
+ support.notifyEntityOwnershipListeners(entity5, true, false, true);
Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
- verify(mockListener1, never()).ownershipChanged(eq(entity4), anyBoolean(), anyBoolean());
- verify(mockListener2, never()).ownershipChanged(eq(entity4), anyBoolean(), anyBoolean());
- verify(mockListener3, never()).ownershipChanged(eq(entity4), anyBoolean(), anyBoolean());
+ verify(mockListener1, never()).ownershipChanged(ownershipChange(entity4));
+ verify(mockListener2, never()).ownershipChanged(ownershipChange(entity4));
+ verify(mockListener3, never()).ownershipChanged(ownershipChange(entity4));
reset(mockListener1, mockListener2, mockListener3);
// Unregister mockListener1 for entity1, issue a change and verify only mockListeners 2 & 3 are notified.
support.removeEntityOwnershipListener(entity1, mockListener1);
- support.notifyEntityOwnershipListeners(entity1, false, true);
+ support.notifyEntityOwnershipListeners(entity1, true, false, true);
- verify(mockListener2, timeout(5000)).ownershipChanged(entity1, false, true);
- verify(mockListener3, timeout(5000)).ownershipChanged(entity1, 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(eq(entity1), anyBoolean(), anyBoolean());
+ 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, true);
+ support.notifyEntityOwnershipListeners(entity1, false, false, false);
- verify(mockListener2, timeout(5000)).ownershipChanged(entity1, false, true);
+ verify(mockListener2, timeout(5000)).ownershipChanged(ownershipChange(entity1, false, false, false));
Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
- verify(mockListener1, never()).ownershipChanged(eq(entity1), anyBoolean(), anyBoolean());
- verify(mockListener3, never()).ownershipChanged(eq(entity1), anyBoolean(), anyBoolean());
+ verify(mockListener1, never()).ownershipChanged(ownershipChange(entity1));
+ verify(mockListener3, never()).ownershipChanged(ownershipChange(entity1));
// Completely unregister all listeners and verify their listener actors are destroyed.
support.addEntityOwnershipListener(entity1, mockListener1);
- support.notifyEntityOwnershipListeners(entity1, false, true);
+ support.notifyEntityOwnershipListeners(entity1, false, false, true);
- verify(mockListener1, timeout(5000)).ownershipChanged(entity1, false, true);
- verify(mockListener2, never()).ownershipChanged(eq(entity1), anyBoolean(), anyBoolean());
- verify(mockListener3, never()).ownershipChanged(eq(entity1), anyBoolean(), anyBoolean());
+ verify(mockListener1, timeout(5000)).ownershipChanged(ownershipChange(entity1, false, false, true));
+ verify(mockListener2, never()).ownershipChanged(ownershipChange(entity1));
+ verify(mockListener3, never()).ownershipChanged(ownershipChange(entity1));
// Quickly register and unregister mockListener2 - expecting no exceptions.
*/
package org.opendaylight.controller.cluster.datastore.entityownership;
-import static org.hamcrest.CoreMatchers.either;
-import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertEquals;
+import static org.mockito.AdditionalMatchers.or;
import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
-import org.hamcrest.Matcher;
import org.junit.After;
import org.junit.Test;
import org.opendaylight.controller.cluster.datastore.AbstractShardTest;
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.yangtools.yang.data.api.YangInstanceIdentifier;
verifyCommittedEntityCandidate(shard, ENTITY_TYPE, entityId, LOCAL_MEMBER_NAME);
verifyOwner(shard, ENTITY_TYPE, entityId, LOCAL_MEMBER_NAME);
- verify(candidate, timeout(5000)).ownershipChanged(entity, false, true);
+ verify(candidate, timeout(5000)).ownershipChanged(ownershipChange(entity, false, true, true));
}
@Test
verifyOwner(shard, ENTITY_TYPE, entityId, LOCAL_MEMBER_NAME);
- verify(candidate, timeout(5000)).ownershipChanged(entity, false, true);
+ verify(candidate, timeout(5000)).ownershipChanged(ownershipChange(entity, false, true, true));
}
@Test
verifyOwner(shard, ENTITY_TYPE, entityId, LOCAL_MEMBER_NAME);
- verify(candidate, timeout(5000)).ownershipChanged(entity, false, true);
+ verify(candidate, timeout(5000)).ownershipChanged(ownershipChange(entity, false, true, true));
}
@Test
verifyOwner(shard, ENTITY_TYPE, entityId, LOCAL_MEMBER_NAME);
- verify(candidate, timeout(5000)).ownershipChanged(entity, false, true);
+ verify(candidate, timeout(5000)).ownershipChanged(ownershipChange(entity, false, true, true));
}
@Test
verifyCommittedEntityCandidate(shard, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
verifyOwner(shard, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
- verify(candidate, timeout(5000)).ownershipChanged(entity, false, true);
+ verify(candidate, timeout(5000)).ownershipChanged(ownershipChange(entity, false, true, true));
// Unregister
kit.expectMsgClass(SuccessReply.class);
verifyOwner(shard, ENTITY_TYPE, ENTITY_ID1, "");
- verify(candidate, never()).ownershipChanged(any(Entity.class), anyBoolean(), anyBoolean());
+ //verify(candidate).ownershipChanged(entity, true, false, false);
// Register again
verifyCommittedEntityCandidate(shard, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
verifyOwner(shard, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
- verify(candidate, timeout(5000)).ownershipChanged(entity, false, true);
+ verify(candidate, timeout(5000)).ownershipChanged(ownershipChange(entity, false, true, true));
}
@Test
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(Entity.class), anyBoolean(), anyBoolean());
+ verify(candidate, never()).ownershipChanged(any(EntityOwnershipChange.class));
// Add another remote candidate and verify ownership doesn't change
verifyCommittedEntityCandidate(shard, ENTITY_TYPE, ENTITY_ID1, remoteMemberName2);
Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS);
verifyOwner(shard, ENTITY_TYPE, ENTITY_ID1, remoteMemberName1);
- verify(candidate, never()).ownershipChanged(any(Entity.class), anyBoolean(), anyBoolean());
+ verify(candidate, never()).ownershipChanged(any(EntityOwnershipChange.class));
// Remove the second remote candidate and verify ownership doesn't change
verifyEntityCandidateRemoved(shard, ENTITY_TYPE, ENTITY_ID1, remoteMemberName2);
Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS);
verifyOwner(shard, ENTITY_TYPE, ENTITY_ID1, remoteMemberName1);
- verify(candidate, never()).ownershipChanged(any(Entity.class), anyBoolean(), anyBoolean());
+ verify(candidate, never()).ownershipChanged(any(EntityOwnershipChange.class));
// Remove the first remote candidate and verify the local candidate becomes owner
verifyEntityCandidateRemoved(shard, ENTITY_TYPE, ENTITY_ID1, remoteMemberName1);
verifyOwner(shard, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
- verify(candidate, timeout(5000)).ownershipChanged(entity, false, true);
+ verify(candidate, timeout(5000)).ownershipChanged(ownershipChange(entity, false, true, true));
// Add the second remote candidate back and verify ownership doesn't change
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(Entity.class), anyBoolean(), anyBoolean());
+ verify(candidate, never()).ownershipChanged(any(EntityOwnershipChange.class));
// Unregister the local candidate and verify the second remote candidate becomes owner
shard.tell(new RegisterCandidateLocal(candidate, entity), kit.getRef());
kit.expectMsgClass(SuccessReply.class);
verifyCommittedEntityCandidate(shard, entity.getType(), entity.getId(), LOCAL_MEMBER_NAME);
- verify(candidate, timeout(5000)).ownershipChanged(entity, false, true);
+ verify(candidate, timeout(5000)).ownershipChanged(ownershipChange(entity, false, true, true));
reset(candidate);
// Simulate a replicated commit from the leader to remove the local candidate that would occur after a
leader.tell(new PeerDown(LOCAL_MEMBER_NAME, localId.toString()), ActorRef.noSender());
- verify(candidate, timeout(5000)).ownershipChanged(entity, true, false);
+ verify(candidate, 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);
- verify(candidate, timeout(5000)).ownershipChanged(entity, false, true);
+ verify(candidate, timeout(5000)).ownershipChanged(ownershipChange(entity, false, true, true));
// Unregister the local candidate and verify it's removed and no re-added.
shard.tell(new RegisterCandidateLocal(candidate, entity1), kit.getRef());
kit.expectMsgClass(SuccessReply.class);
- verify(listener, timeout(5000)).ownershipChanged(entity1, false, true);
+ verify(listener, timeout(5000)).ownershipChanged(ownershipChange(entity1, false, true, true));
shard.tell(new RegisterCandidateLocal(candidate, entity2), kit.getRef());
kit.expectMsgClass(SuccessReply.class);
- verify(listener, timeout(5000)).ownershipChanged(entity2, false, true);
+ verify(listener, timeout(5000)).ownershipChanged(ownershipChange(entity2, false, true, true));
reset(listener);
// Register another candidate for another entity type and verify listener is not notified.
kit.expectMsgClass(SuccessReply.class);
Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS);
- verify(listener, never()).ownershipChanged(eq(entity4), anyBoolean(), anyBoolean());
+ verify(listener, never()).ownershipChanged(ownershipChange(entity4));
// Register remote candidate for entity1
shard.tell(new UnregisterCandidateLocal(candidate, entity1), kit.getRef());
kit.expectMsgClass(SuccessReply.class);
- verify(listener, timeout(5000)).ownershipChanged(entity1, true, false);
+ verify(listener, timeout(5000)).ownershipChanged(ownershipChange(entity1, true, false, true));
reset(listener);
// Unregister the listener, add a candidate for entity3 and verify listener isn't notified
verifyOwner(shard, ENTITY_TYPE, entity3.getId(), LOCAL_MEMBER_NAME);
Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS);
- verify(listener, never()).ownershipChanged(any(Entity.class), anyBoolean(), anyBoolean());
+ verify(listener, never()).ownershipChanged(any(EntityOwnershipChange.class));
- // Re-register the listener and verify it gets notified of current locally owned entities
+ // Re-register the listener and verify it gets notified of currently owned entities
reset(listener, candidate);
shard.tell(new RegisterListenerLocal(listener, ENTITY_TYPE), kit.getRef());
kit.expectMsgClass(SuccessReply.class);
- Matcher<Entity> entityMatcher = either(equalTo(entity2)).or(equalTo(entity3));
- verify(listener, timeout(5000).times(2)).ownershipChanged(argThat(entityMatcher), eq(false), eq(true));
+ verify(listener, timeout(5000).times(2)).ownershipChanged(or(ownershipChange(entity2, false, true, true),
+ ownershipChange(entity3, false, true, true)));
Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
- verify(listener, never()).ownershipChanged(eq(entity4), anyBoolean(), anyBoolean());
- verify(listener, never()).ownershipChanged(eq(entity1), anyBoolean(), anyBoolean());
- verify(candidate, never()).ownershipChanged(eq(entity2), anyBoolean(), anyBoolean());
- verify(candidate, never()).ownershipChanged(eq(entity3), anyBoolean(), anyBoolean());
+ 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,
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.EntityOwnershipService;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
private static class CarEntityOwnershipCandidate implements EntityOwnershipCandidate {
@Override
- public void ownershipChanged(Entity entity, boolean wasOwner, boolean isOwner) {
- LOG.info("ownershipChanged: entity: {}, wasOwner: {}, isOwner: ()", entity, wasOwner, isOwner);
+ public void ownershipChanged(EntityOwnershipChange ownershipChange) {
+ LOG.info("ownershipChanged: {}", ownershipChange);
}
}
}