use of org.opendaylight.mdsal.eos.dom.api.DOMEntity in project controller by opendaylight.
the class EntityOwnershipShard method notifyAllListeners.
private void notifyAllListeners() {
searchForEntities((entityTypeNode, entityNode) -> {
java.util.Optional<DataContainerChild<?, ?>> possibleType = entityTypeNode.getChild(ENTITY_TYPE_NODE_ID);
if (possibleType.isPresent()) {
final boolean hasOwner;
final boolean isOwner;
java.util.Optional<DataContainerChild<?, ?>> possibleOwner = entityNode.getChild(ENTITY_OWNER_NODE_ID);
if (possibleOwner.isPresent()) {
isOwner = localMemberName.getName().equals(possibleOwner.get().getValue().toString());
hasOwner = true;
} else {
isOwner = false;
hasOwner = false;
}
DOMEntity entity = new DOMEntity(possibleType.get().getValue().toString(), (YangInstanceIdentifier) entityNode.getChild(ENTITY_ID_NODE_ID).get().getValue());
listenerSupport.notifyEntityOwnershipListeners(entity, isOwner, isOwner, hasOwner);
}
});
}
use of org.opendaylight.mdsal.eos.dom.api.DOMEntity in project controller by opendaylight.
the class EntityOwnershipListenerActorTest method testOnEntityOwnershipChangedWithListenerEx.
@Test
public void testOnEntityOwnershipChangedWithListenerEx() {
DOMEntityOwnershipListener mockListener = mock(DOMEntityOwnershipListener.class);
DOMEntity entity1 = new DOMEntity("test", YangInstanceIdentifier.of(QName.create("test", "id1")));
doThrow(new RuntimeException("mock")).when(mockListener).ownershipChanged(ownershipChange(entity1, false, true, true));
DOMEntity entity2 = new DOMEntity("test", YangInstanceIdentifier.of(QName.create("test", "id2")));
doNothing().when(mockListener).ownershipChanged(ownershipChange(entity2, true, false, false));
TestActorRef<EntityOwnershipListenerActor> listenerActor = actorFactory.createTestActor(EntityOwnershipListenerActor.props(mockListener), actorFactory.generateActorId("listener"));
listenerActor.tell(new DOMEntityOwnershipChange(entity1, EntityOwnershipChangeState.from(false, true, true)), ActorRef.noSender());
listenerActor.tell(new DOMEntityOwnershipChange(entity2, EntityOwnershipChangeState.from(true, false, false)), ActorRef.noSender());
verify(mockListener, timeout(5000)).ownershipChanged(ownershipChange(entity2, true, false, false));
}
use of org.opendaylight.mdsal.eos.dom.api.DOMEntity in project controller by opendaylight.
the class EntityOwnershipListenerSupportTest method testNotifyEntityOwnershipListeners.
@Test
public void testNotifyEntityOwnershipListeners() {
EntityOwnershipListenerSupport support = new EntityOwnershipListenerSupport(actorContext, "test");
DOMEntityOwnershipListener mockListener1 = mock(DOMEntityOwnershipListener.class, "EntityOwnershipListener1");
DOMEntityOwnershipListener mockListener2 = mock(DOMEntityOwnershipListener.class, "EntityOwnershipListener2");
DOMEntityOwnershipListener mockListener12 = mock(DOMEntityOwnershipListener.class, "EntityOwnershipListener1_2");
String entityType1 = "type1";
String entityType2 = "type2";
final DOMEntity entity1 = new DOMEntity(entityType1, YangInstanceIdentifier.of(QName.create("test", "id1")));
final DOMEntity entity2 = new DOMEntity(entityType2, YangInstanceIdentifier.of(QName.create("test", "id2")));
final DOMEntity entity3 = new DOMEntity("noListener", YangInstanceIdentifier.of(QName.create("test", "id5")));
// Add EntityOwnershipListener registrations.
support.addEntityOwnershipListener(entityType1, mockListener1);
// register again - should be noop
support.addEntityOwnershipListener(entityType1, mockListener1);
support.addEntityOwnershipListener(entityType1, mockListener12);
support.addEntityOwnershipListener(entityType2, mockListener2);
// Notify entity1 changed and verify appropriate listeners are notified.
support.notifyEntityOwnershipListeners(entity1, false, true, true);
verify(mockListener1, timeout(5000)).ownershipChanged(ownershipChange(entity1, false, true, true));
verify(mockListener12, timeout(5000)).ownershipChanged(ownershipChange(entity1, false, true, true));
Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
verify(mockListener2, never()).ownershipChanged(any(DOMEntityOwnershipChange.class));
assertEquals("# of listener actors", 2, actorContext.children().size());
reset(mockListener1, mockListener2, mockListener12);
// Notify entity2 changed and verify appropriate listeners are notified.
support.notifyEntityOwnershipListeners(entity2, false, true, true);
verify(mockListener2, timeout(5000)).ownershipChanged(ownershipChange(entity2, false, true, true));
Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
verify(mockListener1, never()).ownershipChanged(any(DOMEntityOwnershipChange.class));
verify(mockListener12, never()).ownershipChanged(any(DOMEntityOwnershipChange.class));
assertEquals("# of listener actors", 3, actorContext.children().size());
reset(mockListener1, mockListener2, mockListener12);
// Notify entity3 changed and verify no listeners are notified.
support.notifyEntityOwnershipListeners(entity3, true, false, true);
Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
verify(mockListener1, never()).ownershipChanged(any(DOMEntityOwnershipChange.class));
verify(mockListener2, never()).ownershipChanged(any(DOMEntityOwnershipChange.class));
verify(mockListener12, never()).ownershipChanged(any(DOMEntityOwnershipChange.class));
reset(mockListener1, mockListener2, mockListener12);
Iterable<ActorRef> listenerActors = actorContext.children();
assertEquals("# of listener actors", 3, listenerActors.size());
// Unregister mockListener1, issue a change for entity1 and verify only remaining listeners are notified.
support.removeEntityOwnershipListener(entityType1, mockListener1);
support.notifyEntityOwnershipListeners(entity1, true, false, true);
verify(mockListener12, timeout(5000)).ownershipChanged(ownershipChange(entity1, true, false, true));
Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
verify(mockListener1, never()).ownershipChanged(any(DOMEntityOwnershipChange.class));
reset(mockListener1, mockListener2, mockListener12);
// Unregister all listeners and verify their listener actors are destroyed.
List<TestKit> watchers = new ArrayList<>();
for (Iterator<ActorRef> iter = listenerActors.iterator(); iter.hasNext(); ) {
TestKit kit = new TestKit(getSystem());
kit.watch(iter.next());
watchers.add(kit);
}
support.removeEntityOwnershipListener(entityType1, mockListener12);
// un-register again - should be noop
support.removeEntityOwnershipListener(entityType1, mockListener12);
support.removeEntityOwnershipListener(entityType2, mockListener2);
Iterator<ActorRef> iter = listenerActors.iterator();
for (TestKit kit : watchers) {
kit.expectTerminated(kit.duration("3 seconds"), iter.next());
}
assertEquals("# of listener actors", 0, actorContext.children().size());
// Re-register mockListener1 and verify it is notified.
reset(mockListener1, mockListener2);
support.addEntityOwnershipListener(entityType1, mockListener1);
support.notifyEntityOwnershipListeners(entity1, false, false, true);
verify(mockListener1, timeout(5000)).ownershipChanged(ownershipChange(entity1, false, false, true));
verify(mockListener12, never()).ownershipChanged(any(DOMEntityOwnershipChange.class));
verify(mockListener2, never()).ownershipChanged(any(DOMEntityOwnershipChange.class));
// Quickly register and unregister mockListener2 - expecting no exceptions.
support.addEntityOwnershipListener(entityType1, mockListener2);
support.removeEntityOwnershipListener(entityType1, mockListener2);
}
use of org.opendaylight.mdsal.eos.dom.api.DOMEntity in project controller by opendaylight.
the class EntityOwnershipShardTest method testDelayedEntityOwnerSelectionWhenMaxPeerRequestsReceived.
@Test
public void testDelayedEntityOwnerSelectionWhenMaxPeerRequestsReceived() throws Exception {
testLog.info("testDelayedEntityOwnerSelectionWhenMaxPeerRequestsReceived starting");
ShardTestKit kit = new ShardTestKit(getSystem());
EntityOwnerSelectionStrategyConfig.Builder builder = EntityOwnerSelectionStrategyConfig.newBuilder().addStrategy(ENTITY_TYPE, LastCandidateSelectionStrategy.class, 500);
ShardIdentifier leaderId = newShardId(LOCAL_MEMBER_NAME);
ShardIdentifier peerId = newShardId(PEER_MEMBER_1_NAME);
TestActorRef<TestEntityOwnershipShard> peer = actorFactory.createTestActor(TestEntityOwnershipShard.props(newShardBuilder(peerId, peerMap(leaderId.toString()), PEER_MEMBER_1_NAME)), peerId.toString());
peer.underlyingActor().startDroppingMessagesOfType(ElectionTimeout.class);
TestActorRef<EntityOwnershipShard> leader = actorFactory.createTestActor(newShardProps(leaderId, peerMap(peerId.toString()), LOCAL_MEMBER_NAME, builder.build()), leaderId.toString());
ShardTestKit.waitUntilLeader(leader);
DOMEntity entity = new DOMEntity(ENTITY_TYPE, ENTITY_ID1);
// Add a remote candidate
peer.tell(new RegisterCandidateLocal(entity), kit.getRef());
kit.expectMsgClass(SuccessReply.class);
// Register local
leader.tell(new RegisterCandidateLocal(entity), kit.getRef());
kit.expectMsgClass(SuccessReply.class);
// Verify the local candidate becomes owner
verifyCommittedEntityCandidate(leader, entity.getType(), entity.getIdentifier(), PEER_MEMBER_1_NAME);
verifyCommittedEntityCandidate(leader, entity.getType(), entity.getIdentifier(), LOCAL_MEMBER_NAME);
verifyOwner(leader, entity.getType(), entity.getIdentifier(), LOCAL_MEMBER_NAME);
testLog.info("testDelayedEntityOwnerSelectionWhenMaxPeerRequestsReceived ending");
}
use of org.opendaylight.mdsal.eos.dom.api.DOMEntity in project controller by opendaylight.
the class EntityOwnershipShardTest method testOwnerChangesOnPeerAvailabilityChanges.
@Test
public void testOwnerChangesOnPeerAvailabilityChanges() throws Exception {
testLog.info("testOwnerChangesOnPeerAvailabilityChanges starting");
final ShardTestKit kit = new ShardTestKit(getSystem());
dataStoreContextBuilder.shardHeartbeatIntervalInMillis(100).shardElectionTimeoutFactor(4).shardIsolatedLeaderCheckIntervalInMillis(100000);
ShardIdentifier leaderId = newShardId(LOCAL_MEMBER_NAME);
ShardIdentifier peerId1 = newShardId(PEER_MEMBER_1_NAME);
ShardIdentifier peerId2 = newShardId(PEER_MEMBER_2_NAME);
TestActorRef<TestEntityOwnershipShard> peer1 = actorFactory.createTestActor(TestEntityOwnershipShard.props(newShardBuilder(peerId1, peerMap(leaderId.toString(), peerId2.toString()), PEER_MEMBER_1_NAME)), peerId1.toString());
peer1.underlyingActor().startDroppingMessagesOfType(ElectionTimeout.class);
TestActorRef<TestEntityOwnershipShard> peer2 = actorFactory.createTestActor(TestEntityOwnershipShard.props(newShardBuilder(peerId2, peerMap(leaderId.toString(), peerId1.toString()), PEER_MEMBER_2_NAME)), peerId2.toString());
peer2.underlyingActor().startDroppingMessagesOfType(ElectionTimeout.class);
TestActorRef<EntityOwnershipShard> leader = actorFactory.createTestActor(newShardProps(leaderId, peerMap(peerId1.toString(), peerId2.toString()), LOCAL_MEMBER_NAME), leaderId.toString());
verifyRaftState(leader, state -> assertEquals("getRaftState", RaftState.Leader.toString(), state.getRaftState()));
// Send PeerDown and PeerUp with no entities
leader.tell(new PeerDown(peerId2.getMemberName(), peerId2.toString()), ActorRef.noSender());
leader.tell(new PeerUp(peerId2.getMemberName(), peerId2.toString()), ActorRef.noSender());
// Add candidates for entity1 with the local leader as the owner
leader.tell(new RegisterCandidateLocal(new DOMEntity(ENTITY_TYPE, ENTITY_ID1)), kit.getRef());
kit.expectMsgClass(SuccessReply.class);
verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
peer2.tell(new RegisterCandidateLocal(new DOMEntity(ENTITY_TYPE, ENTITY_ID1)), kit.getRef());
kit.expectMsgClass(SuccessReply.class);
verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID1, PEER_MEMBER_2_NAME);
peer1.tell(new RegisterCandidateLocal(new DOMEntity(ENTITY_TYPE, ENTITY_ID1)), kit.getRef());
kit.expectMsgClass(SuccessReply.class);
verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID1, PEER_MEMBER_1_NAME);
verifyOwner(leader, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
// Add candidates for entity2 with peerMember2 as the owner
peer2.tell(new RegisterCandidateLocal(new DOMEntity(ENTITY_TYPE, ENTITY_ID2)), kit.getRef());
kit.expectMsgClass(SuccessReply.class);
verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_2_NAME);
peer1.tell(new RegisterCandidateLocal(new DOMEntity(ENTITY_TYPE, ENTITY_ID2)), kit.getRef());
kit.expectMsgClass(SuccessReply.class);
verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_1_NAME);
verifyOwner(leader, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_2_NAME);
// Add candidates for entity3 with peerMember2 as the owner.
peer2.tell(new RegisterCandidateLocal(new DOMEntity(ENTITY_TYPE, ENTITY_ID3)), kit.getRef());
kit.expectMsgClass(SuccessReply.class);
verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID3, PEER_MEMBER_2_NAME);
leader.tell(new RegisterCandidateLocal(new DOMEntity(ENTITY_TYPE, ENTITY_ID3)), kit.getRef());
kit.expectMsgClass(SuccessReply.class);
verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID3, LOCAL_MEMBER_NAME);
peer1.tell(new RegisterCandidateLocal(new DOMEntity(ENTITY_TYPE, ENTITY_ID3)), kit.getRef());
kit.expectMsgClass(SuccessReply.class);
verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID3, PEER_MEMBER_1_NAME);
verifyOwner(leader, ENTITY_TYPE, ENTITY_ID3, PEER_MEMBER_2_NAME);
// Add only candidate peerMember2 for entity4.
peer2.tell(new RegisterCandidateLocal(new DOMEntity(ENTITY_TYPE, ENTITY_ID4)), kit.getRef());
kit.expectMsgClass(SuccessReply.class);
verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID4, PEER_MEMBER_2_NAME);
verifyOwner(leader, ENTITY_TYPE, ENTITY_ID4, PEER_MEMBER_2_NAME);
// Add only candidate peerMember1 for entity5.
peer1.tell(new RegisterCandidateLocal(new DOMEntity(ENTITY_TYPE, ENTITY_ID5)), kit.getRef());
kit.expectMsgClass(SuccessReply.class);
verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID5, PEER_MEMBER_1_NAME);
verifyOwner(leader, ENTITY_TYPE, ENTITY_ID5, PEER_MEMBER_1_NAME);
// Kill peerMember2 and send PeerDown - the entities (2, 3, 4) owned by peerMember2 should get a new
// owner selected
kit.watch(peer2);
peer2.tell(PoisonPill.getInstance(), ActorRef.noSender());
kit.expectMsgClass(kit.duration("5 seconds"), Terminated.class);
kit.unwatch(peer2);
leader.tell(new PeerDown(peerId2.getMemberName(), peerId2.toString()), ActorRef.noSender());
// Send PeerDown again - should be noop
leader.tell(new PeerDown(peerId2.getMemberName(), peerId2.toString()), ActorRef.noSender());
peer1.tell(new PeerDown(peerId2.getMemberName(), peerId2.toString()), ActorRef.noSender());
verifyOwner(leader, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
verifyOwner(leader, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_1_NAME);
verifyOwner(leader, ENTITY_TYPE, ENTITY_ID3, LOCAL_MEMBER_NAME);
// no other candidates for entity4 so peerMember2 should remain owner.
verifyOwner(leader, ENTITY_TYPE, ENTITY_ID4, PEER_MEMBER_2_NAME);
verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID1, PEER_MEMBER_2_NAME);
verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_2_NAME);
verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID3, PEER_MEMBER_2_NAME);
verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID4, PEER_MEMBER_2_NAME);
// Reinstate peerMember2
peer2 = actorFactory.createTestActor(TestEntityOwnershipShard.props(newShardBuilder(peerId2, peerMap(leaderId.toString(), peerId1.toString()), PEER_MEMBER_2_NAME)), peerId2.toString());
peer2.underlyingActor().startDroppingMessagesOfType(ElectionTimeout.class);
leader.tell(new PeerUp(peerId2.getMemberName(), peerId2.toString()), ActorRef.noSender());
// Send PeerUp again - should be noop
leader.tell(new PeerUp(peerId2.getMemberName(), peerId2.toString()), ActorRef.noSender());
peer1.tell(new PeerUp(peerId2.getMemberName(), peerId2.toString()), ActorRef.noSender());
// peerMember2's candidates should be removed on startup.
verifyNoEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID1, PEER_MEMBER_2_NAME);
verifyNoEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_2_NAME);
verifyNoEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID3, PEER_MEMBER_2_NAME);
verifyNoEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID4, PEER_MEMBER_2_NAME);
verifyOwner(leader, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
verifyOwner(leader, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_1_NAME);
verifyOwner(leader, ENTITY_TYPE, ENTITY_ID3, LOCAL_MEMBER_NAME);
verifyOwner(leader, ENTITY_TYPE, ENTITY_ID4, "");
// Add back candidate peerMember2 for entities 1, 2, & 3.
peer2.tell(new RegisterCandidateLocal(new DOMEntity(ENTITY_TYPE, ENTITY_ID1)), kit.getRef());
kit.expectMsgClass(SuccessReply.class);
peer2.tell(new RegisterCandidateLocal(new DOMEntity(ENTITY_TYPE, ENTITY_ID2)), kit.getRef());
kit.expectMsgClass(SuccessReply.class);
peer2.tell(new RegisterCandidateLocal(new DOMEntity(ENTITY_TYPE, ENTITY_ID3)), kit.getRef());
kit.expectMsgClass(SuccessReply.class);
verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID1, PEER_MEMBER_2_NAME);
verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_2_NAME);
verifyCommittedEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID3, PEER_MEMBER_2_NAME);
verifyCommittedEntityCandidate(peer2, ENTITY_TYPE, ENTITY_ID1, PEER_MEMBER_2_NAME);
verifyCommittedEntityCandidate(peer2, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_2_NAME);
verifyCommittedEntityCandidate(peer2, ENTITY_TYPE, ENTITY_ID3, PEER_MEMBER_2_NAME);
verifyOwner(leader, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
verifyOwner(leader, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_1_NAME);
verifyOwner(leader, ENTITY_TYPE, ENTITY_ID3, LOCAL_MEMBER_NAME);
verifyOwner(peer2, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
verifyOwner(peer2, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_1_NAME);
verifyOwner(peer2, ENTITY_TYPE, ENTITY_ID3, LOCAL_MEMBER_NAME);
verifyOwner(peer2, ENTITY_TYPE, ENTITY_ID4, "");
// Kill peerMember1 and send PeerDown - entity 2 should get a new owner selected
kit.watch(peer1);
peer1.tell(PoisonPill.getInstance(), ActorRef.noSender());
kit.expectMsgClass(kit.duration("5 seconds"), Terminated.class);
kit.unwatch(peer1);
leader.tell(new PeerDown(peerId1.getMemberName(), peerId1.toString()), ActorRef.noSender());
verifyOwner(leader, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_2_NAME);
// Verify the reinstated peerMember2 is fully synced.
verifyOwner(peer2, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
verifyOwner(peer2, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_2_NAME);
verifyOwner(peer2, ENTITY_TYPE, ENTITY_ID3, LOCAL_MEMBER_NAME);
verifyOwner(peer2, ENTITY_TYPE, ENTITY_ID4, "");
// Reinstate peerMember1 and verify no owner changes
peer1 = actorFactory.createTestActor(TestEntityOwnershipShard.props(newShardBuilder(peerId1, peerMap(leaderId.toString(), peerId2.toString()), PEER_MEMBER_1_NAME)), peerId1.toString());
peer1.underlyingActor().startDroppingMessagesOfType(ElectionTimeout.class);
leader.tell(new PeerUp(peerId1.getMemberName(), peerId1.toString()), ActorRef.noSender());
verifyOwner(leader, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
verifyOwner(leader, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_2_NAME);
verifyOwner(leader, ENTITY_TYPE, ENTITY_ID3, LOCAL_MEMBER_NAME);
verifyOwner(leader, ENTITY_TYPE, ENTITY_ID4, "");
verifyNoEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID1, PEER_MEMBER_1_NAME);
verifyNoEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_1_NAME);
verifyNoEntityCandidate(leader, ENTITY_TYPE, ENTITY_ID3, PEER_MEMBER_1_NAME);
verifyNoEntityCandidate(peer2, ENTITY_TYPE, ENTITY_ID1, PEER_MEMBER_1_NAME);
verifyNoEntityCandidate(peer2, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_1_NAME);
verifyNoEntityCandidate(peer2, ENTITY_TYPE, ENTITY_ID3, PEER_MEMBER_1_NAME);
// Verify the reinstated peerMember1 is fully synced.
verifyOwner(peer1, ENTITY_TYPE, ENTITY_ID1, LOCAL_MEMBER_NAME);
verifyOwner(peer1, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_2_NAME);
verifyOwner(peer1, ENTITY_TYPE, ENTITY_ID3, LOCAL_MEMBER_NAME);
verifyOwner(peer1, ENTITY_TYPE, ENTITY_ID4, "");
AtomicLong leaderLastApplied = new AtomicLong();
verifyRaftState(leader, rs -> {
assertEquals("LastApplied up-to-date", rs.getLastApplied(), rs.getLastIndex());
leaderLastApplied.set(rs.getLastApplied());
});
verifyRaftState(peer2, rs -> {
assertEquals("LastApplied", leaderLastApplied.get(), rs.getLastIndex());
});
// Kill the local leader and elect peer2 the leader. This should cause a new owner to be selected for
// the entities (1 and 3) previously owned by the local leader member.
peer2.tell(new PeerAddressResolved(peerId1.toString(), peer1.path().toString()), ActorRef.noSender());
peer2.tell(new PeerUp(leaderId.getMemberName(), leaderId.toString()), ActorRef.noSender());
peer2.tell(new PeerUp(peerId1.getMemberName(), peerId1.toString()), ActorRef.noSender());
kit.watch(leader);
leader.tell(PoisonPill.getInstance(), ActorRef.noSender());
kit.expectMsgClass(kit.duration("5 seconds"), Terminated.class);
kit.unwatch(leader);
peer2.tell(new PeerDown(leaderId.getMemberName(), leaderId.toString()), ActorRef.noSender());
peer2.tell(TimeoutNow.INSTANCE, peer2);
verifyRaftState(peer2, state -> assertEquals("getRaftState", RaftState.Leader.toString(), state.getRaftState()));
verifyOwner(peer2, ENTITY_TYPE, ENTITY_ID1, PEER_MEMBER_2_NAME);
verifyOwner(peer2, ENTITY_TYPE, ENTITY_ID2, PEER_MEMBER_2_NAME);
verifyOwner(peer2, ENTITY_TYPE, ENTITY_ID3, PEER_MEMBER_2_NAME);
verifyOwner(peer2, ENTITY_TYPE, ENTITY_ID4, "");
testLog.info("testOwnerChangesOnPeerAvailabilityChanges ending");
}
Aggregations